VirtualBox

Ignore:
Timestamp:
Apr 9, 2019 1:21:09 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
129883
Message:

IPRT: Working on new RTPathAbsEx implementation, temporarily called RTPathAbsExEx. This should fix most of the bugs in the current RTPathAbs/Ex code and do away with the fixed path buffer limitations. Also introduces a RTPATH_BIG_MAX, given that RTPATH_MAX is just a reasonable and not absolute MAX value. The new one is more or less absolute and must never be used for stack buffers. bugref:9172

Location:
trunk/src/VBox/Runtime/common/path
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/path/RTPathAbsDup.cpp

    r76553 r78048  
    3131#include "internal/iprt.h"
    3232#include <iprt/path.h>
    33 #include <iprt/errcore.h>
     33
     34#include <iprt/err.h>
    3435#include <iprt/param.h>
    3536#include <iprt/string.h>
     
    4546RTDECL(char *) RTPathAbsDup(const char *pszPath)
    4647{
     48    /* Try with a static buffer first. */
    4749    char szPath[RTPATH_MAX];
    4850    int rc = RTPathAbs(pszPath, szPath, sizeof(szPath));
    4951    if (RT_SUCCESS(rc))
    5052        return RTStrDup(szPath);
     53
     54    /* If it looks like we ran out of buffer space, double the size until
     55       we reach 64 KB. */
     56    if (rc == VERR_FILENAME_TOO_LONG || rc == VERR_BUFFER_OVERFLOW)
     57    {
     58        size_t cbBuf = RTPATH_MAX;
     59        do
     60        {
     61            cbBuf *= 2;
     62            char *pszBuf = RTStrAlloc(cbBuf);
     63            if (!pszBuf)
     64                break;
     65            rc = RTPathAbs(pszPath, pszBuf, cbBuf);
     66            if (RT_SUCCESS(rc))
     67                return pszBuf;
     68            RTStrFree(pszBuf);
     69        } while (cbBuf <= _32K);
     70    }
    5171    return NULL;
    5272}
  • trunk/src/VBox/Runtime/common/path/RTPathAbsEx.cpp

    r76553 r78048  
    4949 * @param   pszPath         The path to resolve.
    5050 * @param   pszAbsPath      Where to store the absolute path.
    51  * @param   cchAbsPath      Size of the buffer.
     51 * @param   cbAbsPath       Size of the buffer.
    5252 */
    53 RTDECL(int) RTPathAbsEx(const char *pszBase, const char *pszPath, char *pszAbsPath, size_t cchAbsPath)
     53RTDECL(int) RTPathAbsEx(const char *pszBase, const char *pszPath, char *pszAbsPath, size_t cbAbsPath)
    5454{
     55#if 1
    5556    if (    pszBase
    5657        &&  pszPath
     
    5859       )
    5960    {
    60 #if defined(RT_OS_WINDOWS)
     61# if defined(RT_OS_WINDOWS)
    6162        /* The format for very long paths is not supported. */
    6263        if (    RTPATH_IS_SLASH(pszBase[0])
     
    6667           )
    6768            return VERR_INVALID_NAME;
    68 #endif
     69# endif
    6970
    7071        /** @todo there are a couple of things which isn't 100% correct, although the
     
    9697            memcpy(&szTmpPath[cchBase + 1], pszPath, cchPath + 1);
    9798        }
    98         return RTPathAbs(szTmpPath, pszAbsPath, cchAbsPath);
     99        return RTPathAbs(szTmpPath, pszAbsPath, cbAbsPath);
    99100    }
    100101
    101102    /* Fallback to the non *Ex version */
    102     return RTPathAbs(pszPath, pszAbsPath, cchAbsPath);
     103    return RTPathAbs(pszPath, pszAbsPath, cbAbsPath);
     104#else
     105    return RTPathAbsExEx(pszBase, pszPath, RTPATH_STR_F_STYLE_HOST, pszAbsPath, &cbAbsPath);
     106#endif
    103107}
    104108
  • trunk/src/VBox/Runtime/common/path/RTPathParse.cpp.h

    r76553 r78048  
    5959        }
    6060#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
    61         else if (   RTPATH_IS_SLASH(pszPath[1])
    62                  && !RTPATH_IS_SLASH(pszPath[2])
    63                  && pszPath[2])
    64         {
    65             /* UNC - skip to the end of the potential namespace or computer name. */
     61        else if (RTPATH_IS_SLASH(pszPath[1]))
     62        {
     63            /* UNC - there are exactly two prefix slashes followed by a namespace
     64               or computer name, which can be empty on windows.  */
    6665            offCur = 2;
    6766            while (!RTPATH_IS_SLASH(pszPath[offCur]) && pszPath[offCur])
    6867                offCur++;
    6968
    70             /* If there is another slash, we considered it a valid UNC path, if
    71                not it's just a root path with an extra slash thrown in. */
     69            /* Special fun for windows. */
     70            fProps = RTPATH_PROP_UNC | RTPATH_PROP_ABSOLUTE;
     71            if (   offCur == 3
     72                && (pszPath[2] == '.' || pszPath[2] == '?'))
     73                fProps |= RTPATH_PROP_SPECIAL_UNC;
     74
    7275            if (RTPATH_IS_SLASH(pszPath[offCur]))
    7376            {
    74                 fProps = RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_UNC | RTPATH_PROP_ABSOLUTE;
    75                 offCur++;
    76                 cchPath = offCur;
    77             }
    78             else
    79             {
    80                 fProps = RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE;
    81                 offCur = 1;
    82                 cchPath = 1;
    83             }
     77                fProps |= RTPATH_PROP_ROOT_SLASH;
     78                offCur++;
     79            }
     80            cchPath = offCur;
    8481        }
    8582#endif
  • trunk/src/VBox/Runtime/common/path/RTPathParsedReassemble.cpp

    r76553 r78048  
    4848    AssertReturn(RTPATH_STR_F_IS_VALID(fFlags, 0) && !(fFlags & RTPATH_STR_F_MIDDLE), VERR_INVALID_FLAGS);
    4949    AssertPtrReturn(pszDstPath, VERR_INVALID_POINTER);
    50     AssertReturn(cbDstPath > pParsed->cchPath, VERR_BUFFER_OVERFLOW);
     50
     51    /*
     52     * Recalculate the length.
     53     */
     54    uint32_t const  cComps  = pParsed->cComps;
     55    uint32_t        idxComp = 0;
     56    uint32_t        cchPath = 0;
     57    if (RTPATH_PROP_HAS_ROOT_SPEC(pParsed->fProps))
     58    {
     59        cchPath = pParsed->aComps[0].cch;
     60        idxComp++;
     61    }
     62    bool fNeedSlash = false;
     63    while (idxComp < cComps)
     64    {
     65        uint32_t const cchComp = pParsed->aComps[idxComp].cch;
     66        idxComp++;
     67        if (cchComp > 0)
     68        {
     69            cchPath += cchComp + fNeedSlash;
     70            fNeedSlash = true;
     71        }
     72    }
     73    if ((pParsed->fProps & RTPATH_PROP_DIR_SLASH) && fNeedSlash)
     74        cchPath += 1;
     75    pParsed->cchPath = cchPath;
     76    if (cbDstPath > cchPath)
     77    { /* likely */ }
     78    else
     79    {
     80        if (cbDstPath)
     81            *pszDstPath = '\0';
     82        return VERR_BUFFER_OVERFLOW;
     83    }
    5184
    5285    /*
     
    74107    /*
    75108     * Do the joining.
     109     * Note! Using memmove here as we want to support pszSrcPath == pszDstPath.
    76110     */
    77     uint32_t const  cchOrgPath = pParsed->cchPath;
    78     uint32_t        cchDstPath = 0;
    79     uint32_t const  cComps     = pParsed->cComps;
    80     uint32_t        idxComp    = 0;
    81     char           *pszDst     = pszDstPath;
    82     uint32_t        cchComp;
     111    char *pszDst = pszDstPath;
     112    idxComp      = 0;
     113    fNeedSlash   = false;
    83114
    84115    if (RTPATH_PROP_HAS_ROOT_SPEC(pParsed->fProps))
    85116    {
    86         cchComp = pParsed->aComps[0].cch;
    87         cchDstPath += cchComp;
    88         AssertReturn(cchDstPath <= cchOrgPath, VERR_INVALID_PARAMETER);
    89         memcpy(pszDst, &pszSrcPath[pParsed->aComps[0].off], cchComp);
     117        uint32_t cchComp = pParsed->aComps[0].cch;
     118        memmove(pszDst, &pszSrcPath[pParsed->aComps[0].off], cchComp);
    90119
    91         /* fix the slashes */
     120        /* fix the slashes (harmless for unix style) */
    92121        char chOtherSlash = chSlash == '\\' ? '/' : '\\';
    93122        while (cchComp-- > 0)
     
    102131    while (idxComp < cComps)
    103132    {
    104         cchComp = pParsed->aComps[idxComp].cch;
    105         cchDstPath += cchComp;
    106         AssertReturn(cchDstPath <= cchOrgPath, VERR_INVALID_PARAMETER);
    107         memcpy(pszDst, &pszSrcPath[pParsed->aComps[idxComp].off], cchComp);
    108         pszDst += cchComp;
     133        uint32_t const cchComp = pParsed->aComps[idxComp].cch;
     134        if (cchComp > 0)
     135        {
     136            if (fNeedSlash)
     137                *pszDst++ = chSlash;
     138            fNeedSlash = true;
     139            memmove(pszDst, &pszSrcPath[pParsed->aComps[idxComp].off], cchComp);
     140            pszDst += cchComp;
     141        }
    109142        idxComp++;
    110         if (idxComp != cComps || (pParsed->fProps & RTPATH_PROP_DIR_SLASH))
    111         {
    112             cchDstPath++;
    113             AssertReturn(cchDstPath <= cchOrgPath, VERR_INVALID_PARAMETER);
    114             *pszDst++ = chSlash;
    115         }
    116143    }
    117144
     145    if ((pParsed->fProps & RTPATH_PROP_DIR_SLASH) && fNeedSlash)
     146        *pszDst++ = chSlash;
    118147    *pszDst = '\0';
    119148
Note: See TracChangeset for help on using the changeset viewer.

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