VirtualBox

Changeset 78048 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Apr 9, 2019 1:21:09 AM (6 years ago)
Author:
vboxsync
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
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r77910 r78048  
    512512        common/path/RTPathAbsEx.cpp \
    513513        common/path/RTPathAbsExDup.cpp \
     514        common/path/RTPathAbsExEx.cpp \
    514515        common/path/RTPathAppend.cpp \
    515516        common/path/RTPathAppendEx.cpp \
     
    17061707        common/path/RTPathAbsEx.cpp \
    17071708        common/path/RTPathAbsExDup.cpp \
     1709        common/path/RTPathAbsExEx.cpp \
    17081710        common/path/RTPathAppend.cpp \
    17091711        common/path/RTPathAppendEx.cpp \
     
    27202722        common/path/RTPathAbsEx.cpp \
    27212723        common/path/RTPathAbsExDup.cpp \
     2724        common/path/RTPathAbsExEx.cpp \
    27222725        common/path/RTPathAppend.cpp \
    27232726        common/path/RTPathAppendEx.cpp \
  • 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
  • trunk/src/VBox/Runtime/generic/RTPathAbs-generic.cpp

    r76553 r78048  
    4040#include "internal/fs.h"
    4141
     42#if 1
    4243
    4344static char *rtPathSkipRootSpec(char *pszCur)
     
    145146
    146147
    147 RTDECL(int) RTPathAbs(const char *pszPath, char *pszAbsPath, size_t cchAbsPath)
     148RTDECL(int) RTPathAbs(const char *pszPath, char *pszAbsPath, size_t cbAbsPath)
    148149{
    149150    int rc;
     
    163164    if (cchPath >= RTPATH_MAX)
    164165    {
    165         LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG));
     166        LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cbAbsPath, VERR_FILENAME_TOO_LONG));
    166167        return VERR_FILENAME_TOO_LONG;
    167168    }
     
    179180            || (cchTmpPath == 2 && szTmpPath[1] == RTPATH_SLASH))
    180181        {
    181             rc = RTPathGetCurrent(pszAbsPath, cchAbsPath);
     182            rc = RTPathGetCurrent(pszAbsPath, cbAbsPath);
    182183            if (RT_SUCCESS(rc))
    183184            {
     
    191192                    && (uintptr_t)&pszAbsPath[cch - 1] > (uintptr_t)pszTop && pszAbsPath[cch - 1] != RTPATH_SLASH)
    192193                {
    193                     if (cch + 1 < cchAbsPath)
     194                    if (cch + 1 < cbAbsPath)
    194195                    {
    195196                        pszAbsPath[cch++] = RTPATH_SLASH;
     
    274275        if (RT_FAILURE(rc))
    275276        {
    276             LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath, rc));
     277            LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cbAbsPath, rc));
    277278            return rc;
    278279        }
     
    360361     * Copy the result to the user buffer.
    361362     */
    362     if (cchTmpPath < cchAbsPath)
     363    if (cchTmpPath < cbAbsPath)
    363364    {
    364365        memcpy(pszAbsPath, szTmpPath, cchTmpPath + 1);
     
    369370
    370371    LogFlow(("RTPathAbs(%p:{%s}, %p:{%s}, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath,
    371              RT_SUCCESS(rc) ? pszAbsPath : "<failed>", cchAbsPath, rc));
     372             RT_SUCCESS(rc) ? pszAbsPath : "<failed>", cbAbsPath, rc));
    372373    return rc;
    373374}
    374375
     376#else
     377
     378RTDECL(int) RTPathAbs(const char *pszPath, char *pszAbsPath, size_t cbAbsPath)
     379{
     380    return RTPathAbsExEx(NULL, pszPath, RTPATH_STR_F_STYLE_HOST, pszAbsPath, &cbAbsPath);
     381}
     382
     383#endif
     384
  • trunk/src/VBox/Runtime/generic/RTPathGetCurrentDrive-generic.cpp

    r76553 r78048  
    3535#include <iprt/ctype.h>
    3636#include <iprt/err.h>
     37#include <iprt/mem.h>
    3738#include <iprt/string.h>
    3839#include "internal/path.h"
     
    4546     * Query the current directroy and extract the wanted information from it.
    4647     */
    47     int rc = RTPathGetCurrent(pszPath, cbPath);
     48    char *pszPathFree = NULL;
     49    char *pszCwd = pszPath;
     50    int rc = RTPathGetCurrent(pszCwd, cbPath);
     51    if (RT_SUCCESS(rc))
     52    { /* likely */ }
     53    else if (rc != VERR_BUFFER_OVERFLOW)
     54        return rc;
     55    else
     56    {
     57        pszPathFree = pszCwd = (char *)RTMemTmpAlloc(RTPATH_BIG_MAX);
     58        AssertReturn(pszPathFree, VERR_NO_TMP_MEMORY);
     59        rc = RTPathGetCurrent(pszCwd, RTPATH_BIG_MAX);
     60    }
    4861    if (RT_SUCCESS(rc))
    4962    {
     
    5164         * Drive letter? Chop off at root slash.
    5265         */
    53         if (pszPath[0] && RTPATH_IS_VOLSEP(pszPath[1]))
    54         {
    55             pszPath[2] = '\0';
    56             return rc;
    57         }
    58 
     66        if (pszCwd[0] && RTPATH_IS_VOLSEP(pszCwd[1]))
     67            pszCwd[2] = '\0';
    5968        /*
    6069         * UNC? Chop off after share.
    6170         */
    62         if (   RTPATH_IS_SLASH(pszPath[0])
    63             && RTPATH_IS_SLASH(pszPath[1])
    64             && !RTPATH_IS_SLASH(pszPath[2])
    65             && pszPath[2])
     71        else if (   RTPATH_IS_SLASH(pszCwd[0])
     72                 && RTPATH_IS_SLASH(pszCwd[1])
     73                 && !RTPATH_IS_SLASH(pszCwd[2])
     74                 && pszCwd[2])
    6675        {
    6776            /* Work thru the server name. */
    6877            size_t off = 3;
    69             while (!RTPATH_IS_SLASH(pszPath[off]) && pszPath[off])
     78            while (!RTPATH_IS_SLASH(pszCwd[off]) && pszCwd[off])
    7079                off++;
    7180            size_t offServerSlash = off;
    7281
    7382            /* Is there a share name? */
    74             if (RTPATH_IS_SLASH(pszPath[off]))
     83            if (RTPATH_IS_SLASH(pszCwd[off]))
    7584            {
    76                 while (RTPATH_IS_SLASH(pszPath[off]))
     85                while (RTPATH_IS_SLASH(pszCwd[off]))
    7786                    off++;
    78                 if (pszPath[off])
     87                if (pszCwd[off])
    7988                {
    8089                    /* Work thru the share name. */
    81                     while (!RTPATH_IS_SLASH(pszPath[off]) && pszPath[off])
     90                    while (!RTPATH_IS_SLASH(pszCwd[off]) && pszCwd[off])
    8291                        off++;
    8392                }
     
    8695                    off = offServerSlash;
    8796            }
     97            pszCwd[off] = '\0';
    8898        }
    89         return VERR_INTERNAL_ERROR_4;
     99        else
     100            rc = VERR_INTERNAL_ERROR_4;
     101    }
     102    if (pszPathFree)
     103    {
     104        if (RT_SUCCESS(rc))
     105            rc = RTStrCopy(pszPath, cbPath, pszCwd);
     106        RTMemTmpFree(pszPathFree);
    90107    }
    91108    return rc;
  • trunk/src/VBox/Runtime/testcase/tstRTPath.cpp

    r76660 r78048  
    5757        { 2, 12,  8,  "C:Config.sys",     RTPATH_PROP_VOLUME | RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,                                RTPATH_STR_F_STYLE_DOS },
    5858        { 1, 10,  6,  "Config.sys",       RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,                                                     RTPATH_STR_F_STYLE_DOS },
    59         { 1,  4,  4,  "//./",             RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE,                                                      RTPATH_STR_F_STYLE_DOS },
    60         { 2,  5,  5,  "//./f",            RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                               RTPATH_STR_F_STYLE_DOS },
    61         { 2,  5,  6,  "//.//f",           RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_EXTRA_SLASHES,   RTPATH_STR_F_STYLE_DOS },
    62         { 3,  7,  7,  "//././f",          RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS,        RTPATH_STR_F_STYLE_DOS },
     59        { 1,  4,  4,  "//./",             RTPATH_PROP_UNC | RTPATH_PROP_SPECIAL_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE,                                                      RTPATH_STR_F_STYLE_DOS },
     60        { 2,  5,  5,  "//./f",            RTPATH_PROP_UNC | RTPATH_PROP_SPECIAL_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                               RTPATH_STR_F_STYLE_DOS },
     61        { 2,  5,  6,  "//.//f",           RTPATH_PROP_UNC | RTPATH_PROP_SPECIAL_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_EXTRA_SLASHES,   RTPATH_STR_F_STYLE_DOS },
     62        { 3,  7,  7,  "//././f",          RTPATH_PROP_UNC | RTPATH_PROP_SPECIAL_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS,        RTPATH_STR_F_STYLE_DOS },
    6363        { 3,  8,  8,  "//.././f",         RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS,        RTPATH_STR_F_STYLE_DOS },
    6464        { 3,  9,  9,  "//../../f",        RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOTDOT_REFS,     RTPATH_STR_F_STYLE_DOS },
     
    398398        }
    399399    }
     400
     401    /*
     402     * RTPathAbsExEx - will replace RTPathAbsEx shortly.
     403     */
     404    RTTestSub(hTest, "RTPathAbsExEx");
     405    static const struct
     406    {
     407        uint32_t    fFlags;
     408        const char *pcszInputBase;
     409        const char *pcszInputPath;
     410        int rc;
     411        const char *pcszOutput;
     412    }
     413    s_aRTPathAbsExExTests[] =
     414    {
     415        { RTPATH_STR_F_STYLE_HOST,  NULL, "", VERR_PATH_ZERO_LENGTH, NULL },
     416        { RTPATH_STR_F_STYLE_HOST,  NULL, ".", VINF_SUCCESS, "%p" },
     417#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
     418        { RTPATH_STR_F_STYLE_DOS,   NULL, "\\", VINF_SUCCESS, "%d\\" },
     419        { RTPATH_STR_F_STYLE_DOS,   NULL, "\\..", VINF_SUCCESS, "%d\\" },
     420        { RTPATH_STR_F_STYLE_DOS,   NULL, "/absolute/..", VINF_SUCCESS, "%d\\" },
     421        { RTPATH_STR_F_STYLE_DOS,   NULL, "/absolute\\\\../..", VINF_SUCCESS, "%d\\" },
     422        { RTPATH_STR_F_STYLE_DOS,   NULL, "/absolute//../path\\", VINF_SUCCESS, "%d\\path\\" },
     423        { RTPATH_STR_F_STYLE_DOS,   NULL, "/absolute/../../path", VINF_SUCCESS, "%d\\path" },
     424        { RTPATH_STR_F_STYLE_DOS,   NULL, "relative/../dir\\.\\.\\.\\file.txt", VINF_SUCCESS, "%p\\dir\\file.txt" },
     425        { RTPATH_STR_F_STYLE_DOS,   NULL, "\\data\\", VINF_SUCCESS, "%d\\data\\" },
     426        { RTPATH_STR_F_STYLE_DOS,   "relative_base/dir\\", "\\from_root", VINF_SUCCESS, "%d\\from_root" },
     427        { RTPATH_STR_F_STYLE_DOS,   "relative_base/dir/", "relative_also", VINF_SUCCESS, "%p\\relative_base\\dir\\relative_also" },
     428#else
     429        { RTPATH_STR_F_STYLE_UNIX,  NULL, ".", VINF_SUCCESS, "%p" },
     430        { RTPATH_STR_F_STYLE_UNIX,  NULL, "relative/../dir/./././file.txt", VINF_SUCCESS, "%p/dir/file.txt" },
     431        { RTPATH_STR_F_STYLE_UNIX,  NULL, "relative/../dir\\.\\.\\.\\file.txt", VINF_SUCCESS, "%p/dir\\.\\.\\.\\file.txt" },  /* linux-specific */
     432        { RTPATH_STR_F_STYLE_UNIX,  "relative_base/dir/", "/from_root", VINF_SUCCESS, "/from_root" },
     433        { RTPATH_STR_F_STYLE_UNIX,  "relative_base/dir/", "relative_also", VINF_SUCCESS, "%p/relative_base/dir/relative_also" },
     434#endif
     435        { RTPATH_STR_F_STYLE_UNIX,  NULL, "/", VINF_SUCCESS, "/" },
     436        { RTPATH_STR_F_STYLE_UNIX,  NULL, "/..", VINF_SUCCESS, "/" },
     437        { RTPATH_STR_F_STYLE_UNIX,  NULL, "/absolute/..", VINF_SUCCESS, "/" },
     438        { RTPATH_STR_F_STYLE_UNIX,  NULL, "/absolute\\\\../..", VINF_SUCCESS, "/" },
     439        { RTPATH_STR_F_STYLE_UNIX,  NULL, "/absolute//../path/", VINF_SUCCESS, "/path/" },
     440        { RTPATH_STR_F_STYLE_UNIX,  NULL, "/absolute/../../path", VINF_SUCCESS, "/path" },
     441        { RTPATH_STR_F_STYLE_UNIX,  NULL, "/data/", VINF_SUCCESS, "/data/" },
     442#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
     443        { RTPATH_STR_F_STYLE_DOS,   NULL, "C:\\", VINF_SUCCESS, "C:\\" },
     444        { RTPATH_STR_F_STYLE_DOS,   "C:\\", "..", VINF_SUCCESS, "C:\\" },
     445        { RTPATH_STR_F_STYLE_DOS,   "C:\\temp", "..", VINF_SUCCESS, "C:\\" },
     446        { RTPATH_STR_F_STYLE_DOS,   "C:\\VirtualBox/Machines", "..\\VirtualBox.xml", VINF_SUCCESS, "C:\\VirtualBox\\VirtualBox.xml" },
     447        { RTPATH_STR_F_STYLE_DOS,   "C:\\MustDie", "\\from_root/dir/..", VINF_SUCCESS, "C:\\from_root" },
     448        { RTPATH_STR_F_STYLE_DOS,   "C:\\temp", "D:\\data", VINF_SUCCESS, "D:\\data" },
     449        { RTPATH_STR_F_STYLE_DOS,   NULL, "\\\\server\\..\\share", VINF_SUCCESS, "\\\\server\\..\\share" /* kind of strange */ },
     450        { RTPATH_STR_F_STYLE_DOS,   NULL, "\\\\server/", VINF_SUCCESS, "\\\\server\\" },
     451        { RTPATH_STR_F_STYLE_DOS,   NULL, "\\\\", VINF_SUCCESS, "\\\\" },
     452        { RTPATH_STR_F_STYLE_DOS,   NULL, "\\\\\\something", VINF_SUCCESS, "\\\\\\something" /* kind of strange */ },
     453        { RTPATH_STR_F_STYLE_DOS,   "\\\\server\\share_as_base", "/from_root", VINF_SUCCESS, "\\\\server\\share_as_base\\from_root" },
     454        { RTPATH_STR_F_STYLE_DOS,   "\\\\just_server", "/from_root", VINF_SUCCESS, "\\\\just_server\\from_root" },
     455        { RTPATH_STR_F_STYLE_DOS,   "\\\\server\\share_as_base", "relative\\data", VINF_SUCCESS, "\\\\server\\share_as_base\\relative\\data" },
     456        { RTPATH_STR_F_STYLE_DOS,   "base", "\\\\?\\UNC\\relative/edwef/..", VINF_SUCCESS, "\\\\?\\UNC\\relative" },
     457        { RTPATH_STR_F_STYLE_DOS,   "\\\\?\\UNC\\base", "/from_root", VINF_SUCCESS, "\\\\?\\from_root" },
     458        { RTPATH_STR_F_STYLE_DOS,   "\\\\?\\UNC\\base", "./..", VINF_SUCCESS, "\\\\?\\UNC" },
     459        { RTPATH_STR_F_STYLE_DOS | RTPATHABS_F_STOP_AT_BASE, "\\\\?\\UNC\\base", "./..", VINF_SUCCESS, "\\\\?\\UNC\\base" },
     460        { RTPATH_STR_F_STYLE_DOS | RTPATHABS_F_STOP_AT_BASE, "\\\\?\\UNC\\base", "/..", VINF_SUCCESS, "\\\\?\\" },
     461        { RTPATH_STR_F_STYLE_DOS,   NULL, "\\\\.\\asdf\\..", VINF_SUCCESS, "\\\\.\\" },
     462        { RTPATH_STR_F_STYLE_DOS,   NULL, "\\\\?\\asdf\\..", VINF_SUCCESS, "\\\\?\\" },
     463        { RTPATH_STR_F_STYLE_DOS,   NULL, "\\\\x\\asdf\\..", VINF_SUCCESS, "\\\\x\\asdf" },
     464#else
     465        { RTPATH_STR_F_STYLE_UNIX,  "\\temp", "\\data", VINF_SUCCESS, "%p/\\temp/\\data" },
     466#endif
     467        { RTPATH_STR_F_STYLE_UNIX,  "/VirtualBox/Machines", "../VirtualBox.xml", VINF_SUCCESS, "/VirtualBox/VirtualBox.xml" },
     468        { RTPATH_STR_F_STYLE_UNIX,  "/MustDie", "/from_root/dir/..", VINF_SUCCESS, "/from_root" },
     469        { RTPATH_STR_F_STYLE_UNIX,  "/temp", "..", VINF_SUCCESS, "/" },
     470    };
     471    for (unsigned i = 0; i < RT_ELEMENTS(s_aRTPathAbsExExTests); ++ i)
     472    {
     473        if (RT_FAILURE(s_aRTPathAbsExExTests[i].rc))
     474            RTTestDisableAssertions(hTest);
     475
     476        size_t cbAbsPath = sizeof(szPath);
     477        rc = RTPathAbsExEx(s_aRTPathAbsExExTests[i].pcszInputBase,
     478                           s_aRTPathAbsExExTests[i].pcszInputPath,
     479                           s_aRTPathAbsExExTests[i].fFlags,
     480                           szPath, &cbAbsPath);
     481
     482        if (RT_FAILURE(s_aRTPathAbsExExTests[i].rc))
     483            RTTestRestoreAssertions(hTest);
     484
     485        if (rc != s_aRTPathAbsExExTests[i].rc)
     486        {
     487            RTTestIFailed("#%u: unexpected result code!\n"
     488                          "        flags: %#x\n"
     489                          "   input base: '%s'\n"
     490                          "   input path: '%s'\n"
     491                          "       output: '%s'\n"
     492                          "           rc: %Rrc\n"
     493                          "  expected rc: %Rrc",
     494                          i,
     495                          s_aRTPathAbsExExTests[i].fFlags,
     496                          s_aRTPathAbsExExTests[i].pcszInputBase,
     497                          s_aRTPathAbsExExTests[i].pcszInputPath,
     498                          szPath, rc,
     499                          s_aRTPathAbsExExTests[i].rc);
     500            continue;
     501        }
     502
     503        char szTmp[RTPATH_MAX];
     504        char *pszExpected = NULL;
     505        if (s_aRTPathAbsExExTests[i].pcszOutput != NULL)
     506        {
     507            if (s_aRTPathAbsExExTests[i].pcszOutput[0] == '%')
     508            {
     509                RTTESTI_CHECK_RC(rc = RTPathGetCurrent(szTmp, sizeof(szTmp)), VINF_SUCCESS);
     510                if (RT_FAILURE(rc))
     511                    break;
     512
     513                pszExpected = szTmp;
     514
     515                if (s_aRTPathAbsExExTests[i].pcszOutput[1] == 'p')
     516                {
     517                    cch = strlen(szTmp);
     518                    if (cch + strlen(s_aRTPathAbsExExTests[i].pcszOutput) - 2 <= sizeof(szTmp))
     519                        strcpy(szTmp + cch, s_aRTPathAbsExExTests[i].pcszOutput + 2);
     520                }
     521#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
     522                else if (s_aRTPathAbsExExTests[i].pcszOutput[1] == 'd')
     523                {
     524                    if (2 + strlen(s_aRTPathAbsExExTests[i].pcszOutput) - 2 <= sizeof(szTmp))
     525                        strcpy(szTmp + 2, s_aRTPathAbsExExTests[i].pcszOutput + 2);
     526                }
     527#endif
     528            }
     529            else
     530            {
     531                strcpy(szTmp, s_aRTPathAbsExExTests[i].pcszOutput);
     532                pszExpected = szTmp;
     533            }
     534
     535            if (   strcmp(szPath, pszExpected)
     536                || strlen(szPath) != cbAbsPath)
     537            {
     538                RTTestIFailed("#%u: Unexpected result\n"
     539                              "        flags: %#x\n"
     540                              "   input base: '%s'\n"
     541                              "   input path: '%s'\n"
     542                              "       output: '%s'\n"
     543                              "     expected: '%s' ('%s')\n"
     544                              "    cchResult: %#x, actual %#x",
     545                              i,
     546                              s_aRTPathAbsExExTests[i].fFlags,
     547                              s_aRTPathAbsExExTests[i].pcszInputBase,
     548                              s_aRTPathAbsExExTests[i].pcszInputPath,
     549                              szPath,
     550                              pszExpected, s_aRTPathAbsExExTests[i].pcszOutput,
     551                              cbAbsPath, strlen(szPath));
     552            }
     553        }
     554    }
     555
    400556
    401557    /*
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