VirtualBox

Changeset 15805 in vbox


Ignore:
Timestamp:
Jan 5, 2009 3:03:36 PM (16 years ago)
Author:
vboxsync
Message:

RTPathAbs/posix: man strcpy 'The strings may not overlap, ...' -> memmove. style

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/path-posix.cpp

    r15756 r15805  
    169169RTDECL(int) RTPathAbs(const char *pszPath, char *pszAbsPath, size_t cchAbsPath)
    170170{
    171     if (strlen(pszPath) > PATH_MAX)
    172     {
    173         LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath,
    174                  pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG));
     171    int rc;
     172
     173    /*
     174     * Make a clean working copy of the input.
     175     */
     176    size_t cchPath = strlen(pszPath);
     177    if (cchPath > PATH_MAX)
     178    {
     179        LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG));
    175180        return VERR_FILENAME_TOO_LONG;
    176181    }
    177182
    178183    char szTmpPath[PATH_MAX + 1];
    179     strcpy(szTmpPath, pszPath);
    180     fsCleanPath(szTmpPath);
    181 
    182     /*
    183      * fsCleanPath will leave the single dot alone, we don't need it here.
    184      */
     184    memcpy(szTmpPath, pszPath, cchPath + 1);
     185    size_t cchTmpPath = fsCleanPath(szTmpPath);
     186
     187    /* fsCleanPath will leave the single dot alone, we don't need it here. */
    185188    if (szTmpPath[0] == '.' && !szTmpPath[1])
    186189        szTmpPath[0] = '\0';
    187190
     191    /*
     192     * Do we have a root slash?
     193     */
    188194    char *pszCur = szTmpPath;
    189 
    190195#ifdef HAVE_DRIVE
    191196    if (pszCur[0] && RTPATH_IS_VOLSEP(pszCur[1]) && pszCur[2] == '/')
    192197        pszCur += 3;
    193 #ifdef HAVE_UNC
    194     else
    195     if (pszCur[0] == '/' && pszCur[1] == '/')
     198# ifdef HAVE_UNC
     199    else if (pszCur[0] == '/' && pszCur[1] == '/')
    196200        pszCur += 2;
    197 #endif
    198 #else
     201# endif
     202#else  /* !HAVE_DRIVE */
    199203    if (pszCur[0] == '/')
    200204        pszCur += 1;
    201 #endif
     205#endif /* !HAVE_DRIVE */
    202206    else
    203207    {
    204208        /*
    205          * Prepend the current directory to the relative path.
     209         * No, prepend the current directory to the relative path.
    206210         */
    207 
    208         char szCurDir[PATH_MAX + 1];
    209         if (getcwd(szCurDir, sizeof(szCurDir)) == NULL)
    210         {
    211             AssertMsgFailed(("Couldn't get cwd!\n"));
    212 
    213             int rc = RTErrConvertFromErrno(errno);
    214             LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath,
    215                      pszPath, pszAbsPath, cchAbsPath, rc));
     211        /** @todo use RTPathGetCurrent */
     212        char szNativeCurDir[PATH_MAX + 1];
     213        if (getcwd(szNativeCurDir, sizeof(szNativeCurDir)) == NULL)
     214        {
     215            rc = RTErrConvertFromErrno(errno);
     216            AssertMsgFailedReturn(("Couldn't get cwd! rc=%Rrc errno=%d\n", rc, errno), rc);
     217        }
     218
     219        char *pszCurDir;
     220        rc = rtPathFromNative(&pszCurDir, szNativeCurDir);
     221        if (RT_FAILURE(rc))
     222        {
     223            LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath, rc));
    216224            return rc;
    217225        }
    218226
    219         fsCleanPath(szCurDir);
    220 
    221         {
    222             char *pszUtf8CurDir;
    223             int rc = rtPathFromNative(&pszUtf8CurDir, szCurDir);
    224             if (RT_FAILURE(rc))
    225             {
    226                 LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath,
    227                          pszPath, pszAbsPath, cchAbsPath, rc));
    228                 return rc;
    229             }
    230 
    231             size_t cchUtf8CurDir = strlen(pszUtf8CurDir);
    232             if (cchUtf8CurDir + strlen(szTmpPath) + 1 > PATH_MAX)
    233             {
    234                 RTStrFree(pszUtf8CurDir);
    235                 LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath,
    236                          pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG));
    237                 return VERR_FILENAME_TOO_LONG;
    238             }
    239 
    240             strcpy(szTmpPath + cchUtf8CurDir + 1, szTmpPath);
    241             strcpy(szTmpPath, pszUtf8CurDir);
    242             szTmpPath[cchUtf8CurDir] = '/';
    243 
    244             RTStrFree(pszUtf8CurDir);
    245         }
     227        size_t cchCurDir = fsCleanPath(pszCurDir); /* paranoia */
     228        if (cchCurDir + cchTmpPath + 1 > PATH_MAX)
     229        {
     230            RTStrFree(pszCurDir);
     231            LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG));
     232            return VERR_FILENAME_TOO_LONG;
     233        }
     234
     235        memmove(szTmpPath + cchCurDir + 1, szTmpPath, cchTmpPath + 1);
     236        memcpy(szTmpPath, pszCurDir, cchCurDir);
     237        szTmpPath[cchCurDir] = '/';
     238
     239        RTStrFree(pszCurDir);
    246240
    247241#ifdef HAVE_DRIVE
    248242        if (pszCur[0] && RTPATH_IS_VOLSEP(pszCur[1]) && pszCur[2] == '/')
    249243            pszCur += 3;
    250 #ifdef HAVE_UNC
    251         else
    252         if (pszCur[0] == '/' && pszCur[1] == '/')
     244# ifdef HAVE_UNC
     245        else if (pszCur[0] == '/' && pszCur[1] == '/')
    253246            pszCur += 2;
    254 #endif
     247# endif
    255248#else
    256249        if (pszCur[0] == '/')
     
    258251#endif
    259252        else
    260         {
    261             AssertFailed();
    262             LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath,
    263                      pszPath, pszAbsPath, cchAbsPath, VERR_GENERAL_FAILURE));
    264             return VERR_GENERAL_FAILURE;
    265         }
     253            AssertMsgFailedReturn(("pszCur=%s\n", pszCur), VERR_INTERNAL_ERROR);
    266254    }
    267255
     
    271259     * Get rid of double dot path components by evaluating them.
    272260     */
    273 
    274261    for (;;)
    275262    {
    276         if (pszCur[0] == '.' && pszCur[1] == '.' &&
    277             (!pszCur[2] || pszCur[2] == '/'))
     263        if (   pszCur[0] == '.'
     264            && pszCur[1] == '.'
     265            && (!pszCur[2] || pszCur[2] == '/'))
    278266        {
    279267            /* rewind to the previous component if any */
     
    283271                    ;
    284272
    285             AssertMsg(*pszPrev == '/', ("szTmpPath={%s}, pszPrev=+%u\n",
    286                                         szTmpPath, pszPrev - szTmpPath));
    287             strcpy(pszPrev, pszCur + 2);
     273            AssertMsg(*pszPrev == '/', ("szTmpPath={%s}, pszPrev=+%u\n", szTmpPath, pszPrev - szTmpPath));
     274            memmove(pszPrev, pszCur + 2, strlen(pszCur + 2) + 1);
    288275
    289276            pszCur = pszPrev;
     
    291278        else
    292279        {
     280            /* advance to end of component. */
    293281            while (*pszCur && *pszCur != '/')
    294                 ++pszCur;
     282                pszCur++;
    295283        }
    296284
     
    305293    {
    306294        /*
    307          * We overwrote the trailing slash of the root path with zero, restore
    308          * it.
     295         * We overwrote the root slash with '\0', restore it.
    309296         */
    310297        *pszCur++ = '/';
    311298        *pszCur = '\0';
    312299    }
    313     else if (pszCur > pszTop && *(pszCur - 1) == '/')
     300    else if (pszCur > pszTop && pszCur[-1] == '/')
    314301    {
    315302        /*
    316303         * Extra trailing slash in a non-root path, remove it.
     304         * (A bit questionable...)
    317305         */
    318306        *--pszCur = '\0';
    319307    }
    320308
    321     int rc = VINF_SUCCESS;
    322 
    323     size_t cch = pszCur - szTmpPath + 1;
    324     if (cch <= cchAbsPath)
    325         memcpy(pszAbsPath, szTmpPath, cch);
     309    /*
     310     * Copy the result to the user buffer.
     311     */
     312    cchTmpPath = pszCur - szTmpPath;
     313    if (cchTmpPath < cchAbsPath)
     314    {
     315        memcpy(pszAbsPath, szTmpPath, cchTmpPath + 1);
     316        rc = VINF_SUCCESS;
     317    }
    326318    else
    327319        rc = VERR_BUFFER_OVERFLOW;
    328320
    329     LogFlow(("RTPathAbs(%p:{%s}, %p:{%s}, %d): returns %Rrc\n", pszPath,
    330              pszPath, pszAbsPath, RT_SUCCESS(rc) ? pszAbsPath : "<failed>",
    331              cchAbsPath, rc));
     321    LogFlow(("RTPathAbs(%p:{%s}, %p:{%s}, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath,
     322             RT_SUCCESS(rc) ? pszAbsPath : "<failed>", cchAbsPath, rc));
    332323    return rc;
    333324}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette