VirtualBox

Changeset 58068 in vbox for trunk/src


Ignore:
Timestamp:
Oct 6, 2015 11:47:43 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
103124
Message:

IPRT: Added RTUriFilePathEx, removed RTUriFileNPath as we ignored the cchMax param. Fixed special handling of 'file://localhost/C:/Windows/memory.dmp' style URLs as well as teating '|' as an alternative to the drive letter ':' character. Also extended testcases with windows legacy encodings and taught RTUriFilePathEx to handle them. (RTUriFilePath is calling RTUriFilePathEx of course.)

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/misc/uri.cpp

    r58067 r58068  
    159159{
    160160    AssertReturn(pszString, VERR_INVALID_POINTER);
     161    AssertPtrReturn(pszDst, VERR_INVALID_POINTER);
    161162
    162163    /*
     
    259260        size_t cchDecoded = pchDst - pszDecoded;
    260261        Assert(cchDecoded <= cchString);
    261         // if (cchString - cchDecoded > 64)  -  enable later!
     262        if (cchString - cchDecoded > 64)
    262263            RTStrRealloc(&pszDecoded, cchDecoded + 1);
    263264    }
    264265    return pszDecoded;
    265266}
     267
     268
     269/**
     270 * Calculates the decoded string length.
     271 *
     272 * @returns Number of chars (excluding the terminator).
     273 * @param   pszString       The string to decode.
     274 * @param   cchMax          The maximum string length (e.g. RTSTR_MAX).
     275 */
     276static size_t rtUriCalcDecodedLength(const char *pszString, size_t cchMax)
     277{
     278    size_t cchDecoded;
     279    if (pszString)
     280    {
     281        size_t cchSrcLeft = cchDecoded = RTStrNLen(pszString, cchMax);
     282        while (cchSrcLeft-- > 0)
     283        {
     284            char const ch = *pszString++;
     285            if (ch != '%')
     286            { /* typical */}
     287            else if (   cchSrcLeft >= 2
     288                     && RT_C_IS_XDIGIT(pszString[0])
     289                     && RT_C_IS_XDIGIT(pszString[1]))
     290            {
     291                cchDecoded -= 2;
     292                pszString  += 2;
     293                cchSrcLeft -= 2;
     294            }
     295        }
     296    }
     297    else
     298        cchDecoded = 0;
     299    return cchDecoded;
     300}
     301
     302
     303/**
     304 * Decodes a string into a buffer.
     305 *
     306 * @returns IPRT status code.
     307 * @param   pchSrc      The source string.
     308 * @param   cchSrc      The max number of bytes to decode in the source string.
     309 * @param   pszDst      The destination buffer.
     310 * @param   cbDst       The size of the buffer (including terminator).
     311 */
     312static int rtUriDecodeIntoBuffer(const char *pchSrc, size_t cchSrc, char *pszDst, size_t cbDst)
     313{
     314    AssertPtrReturn(pchSrc, VERR_INVALID_POINTER);
     315    AssertPtrReturn(pszDst, VERR_INVALID_POINTER);
     316
     317    /*
     318     * Knowing that the pszString itself is valid UTF-8, we only have to
     319     * validate the escape sequences.
     320     */
     321    cchSrc = RTStrNLen(pchSrc, cchSrc);
     322    while (cchSrc > 0)
     323    {
     324        const char *pchPct = (const char *)memchr(pchSrc, '%', cchSrc);
     325        if (pchPct)
     326        {
     327            size_t cchBefore = pchPct - pchSrc;
     328            AssertReturn(cchBefore + 1 < cbDst, VERR_BUFFER_OVERFLOW);
     329            if (cchBefore)
     330            {
     331                memcpy(pszDst, pchSrc, cchBefore);
     332                pszDst += cchBefore;
     333                cbDst  -= cchBefore;
     334                pchSrc += cchBefore;
     335                cchSrc -= cchBefore;
     336            }
     337
     338            char chHigh, chLow;
     339            if (   cchSrc >= 3
     340                && RT_C_IS_XDIGIT(chHigh = pchSrc[1])
     341                && RT_C_IS_XDIGIT(chLow  = pchSrc[2]))
     342            {
     343                uint8_t b = RT_C_IS_DIGIT(chHigh) ? chHigh - '0' : (chHigh & ~0x20) - 'A' + 10;
     344                b <<= 4;
     345                b |= RT_C_IS_DIGIT(chLow) ? chLow - '0' : (chLow & ~0x20) - 'A' + 10;
     346                *pszDst++ = (char)b;
     347                pchSrc += 3;
     348                cchSrc -= 3;
     349            }
     350            else
     351            {
     352                AssertFailed();
     353                *pszDst++ = *pchSrc++;
     354                cchSrc--;
     355            }
     356            cbDst -= 1;
     357        }
     358        else
     359        {
     360            AssertReturn(cchSrc < cbDst, VERR_BUFFER_OVERFLOW);
     361            memcpy(pszDst, pchSrc, cchSrc);
     362            pszDst += cchSrc;
     363            cbDst  -= cchSrc;
     364            pchSrc += cchSrc;
     365            cchSrc  = 0;
     366            break;
     367        }
     368    }
     369
     370    AssertReturn(cbDst > 0, VERR_BUFFER_OVERFLOW);
     371    *pszDst = '\0';
     372    return VINF_SUCCESS;
     373}
     374
    266375
    267376
     
    838947
    839948
    840 RTDECL(char *) RTUriFilePath(const char *pszUri, uint32_t uFormat)
    841 {
    842     return RTUriFileNPath(pszUri, uFormat, RTSTR_MAX);
    843 }
    844 
    845 
    846 RTDECL(char *) RTUriFileNPath(const char *pszUri, uint32_t uFormat, size_t cchMax)
    847 {
    848     AssertPtrReturn(pszUri, NULL);
    849     AssertReturn(uFormat == URI_FILE_FORMAT_AUTO || uFormat == URI_FILE_FORMAT_UNIX || uFormat == URI_FILE_FORMAT_WIN, NULL);
    850 
    851     /* Auto is based on the current OS. */
    852     if (uFormat == URI_FILE_FORMAT_AUTO)
    853 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    854         uFormat = URI_FILE_FORMAT_WIN;
    855 #else
    856         uFormat = URI_FILE_FORMAT_UNIX;
    857 #endif
    858 
    859     /* Check that this is a file URI. */
    860     if (RTStrNICmp(pszUri, RT_STR_TUPLE("file:")) != 0)
    861         return NULL;
    862 
     949RTDECL(int) RTUriFilePathEx(const char *pszUri, uint32_t fPathStyle, char **ppszPath, size_t cbPath, size_t *pcchPath)
     950{
     951    /*
     952     * Validate and adjust input.
     953     */
     954    if (pcchPath)
     955    {
     956        AssertPtrReturn(pcchPath, VERR_INVALID_POINTER);
     957        *pcchPath = ~(size_t)0;
     958    }
     959    AssertPtrReturn(ppszPath, VERR_INVALID_POINTER);
     960    AssertReturn(!(fPathStyle & ~RTPATH_STR_F_STYLE_MASK) && fPathStyle != RTPATH_STR_F_STYLE_RESERVED, VERR_INVALID_FLAGS);
     961    if (fPathStyle == RTPATH_STR_F_STYLE_HOST)
     962        fPathStyle = RTPATH_STYLE;
     963    AssertPtrReturn(pszUri, VERR_INVALID_POINTER);
     964
     965    /*
     966     * Check that this is a file URI.
     967     */
     968    if (RTStrNICmp(pszUri, RT_STR_TUPLE("file:")) == 0)
     969    { /* likely */ }
     970    else
     971        return VERR_URI_NOT_FILE_SCHEME;
     972
     973    /*
     974     * We may have a number of variations here, mostly thanks to
     975     * various windows software.  First the canonical variations:
     976     *     - file:///C:/Windows/System32/kernel32.dll
     977     *     - file:///C|/Windows/System32/kernel32.dll
     978     *     - file:///C:%5CWindows%5CSystem32%5Ckernel32.dll
     979     *     - file://localhost/C:%5CWindows%5CSystem32%5Ckernel32.dll
     980     *     - file://cifsserver.dev/systemshare%5CWindows%5CSystem32%5Ckernel32.dll
     981     *     - file://cifsserver.dev:139/systemshare%5CWindows%5CSystem32%5Ckernel32.dll  (not quite sure here, but whatever)
     982     *
     983     * Legacy variant without any slashes after the schema:
     984     *     - file:C:/Windows/System32/kernel32.dll
     985     *     - file:C|/Windows/System32%5Ckernel32.dll
     986     *     - file:~/.bashrc
     987     *            \--path-/
     988     *
     989     * Legacy variant with exactly one slashes after the schema:
     990     *     - file:/C:/Windows/System32%5Ckernel32.dll
     991     *     - file:/C|/Windows/System32/kernel32.dll
     992     *     - file:/usr/bin/env
     993     *            \---path---/
     994     *
     995     * Legacy variant with two slashes after the schema and an unescaped DOS path:
     996     *     - file://C:/Windows/System32\kernel32.dll (**)
     997     *     - file://C|/Windows/System32\kernel32.dll
     998     *                \---path---------------------/
     999     *              -- authority, with ':' as non-working port separator
     1000     *
     1001     * Legacy variant with exactly four slashes after the schema and an unescaped DOS path.
     1002     *     - file:////C:/Windows\System32\user32.dll
     1003     *
     1004     * Legacy variant with four or more slashes after the schema and an unescaped UNC path:
     1005     *     - file:////cifsserver.dev/systemshare/System32%\kernel32.dll
     1006     *     - file://///cifsserver.dev/systemshare/System32\kernel32.dll
     1007     *              \---path--------------------------------------------/
     1008     *
     1009     * The the two unescaped variants shouldn't be handed to rtUriParse, which
     1010     * is good as we cannot actually handle the one marked by (**).  So, handle
     1011     * those two special when parsing.
     1012     */
    8631013    RTURIPARSED Parsed;
    864     int rc = rtUriParse(pszUri, &Parsed);
     1014    int         rc;
     1015    size_t      cSlashes = 0;
     1016    while (pszUri[5 + cSlashes] == '/')
     1017        cSlashes++;
     1018    if (   (cSlashes == 2 || cSlashes == 4)
     1019        && RT_C_IS_ALPHA(pszUri[5 + cSlashes])
     1020        && (pszUri[5 + cSlashes + 1] == ':' || pszUri[5 + cSlashes + 1] == '|'))
     1021    {
     1022        RT_ZERO(Parsed); /* RTURIPARSED_F_CONTAINS_ESCAPED_CHARS is now clear. */
     1023        Parsed.offPath = 5 + cSlashes;
     1024        Parsed.cchPath = strlen(&pszUri[Parsed.offPath]);
     1025        rc = RTStrValidateEncoding(&pszUri[Parsed.offPath]);
     1026    }
     1027    else if (cSlashes >= 4)
     1028    {
     1029        RT_ZERO(Parsed);
     1030        Parsed.fFlags  = cSlashes > 4 ? RTURIPARSED_F_CONTAINS_ESCAPED_CHARS : 0;
     1031        Parsed.offPath = 5 + cSlashes - 2;
     1032        Parsed.cchPath = strlen(&pszUri[Parsed.offPath]);
     1033        rc = RTStrValidateEncoding(&pszUri[Parsed.offPath]);
     1034    }
     1035    else
     1036        rc = rtUriParse(pszUri, &Parsed);
    8651037    if (RT_SUCCESS(rc))
    8661038    {
    867         /* No path detected? Take authority as path then. */
    868         if (!Parsed.cchPath)
    869         {
    870             Parsed.cchPath      = Parsed.cchAuthority;
    871             Parsed.offPath      = Parsed.offAuthority;
    872             Parsed.cchAuthority = 0;
    873         }
    874     }
    875 
    876     if (   RT_SUCCESS(rc)
    877         && Parsed.cchPath)
    878     {
     1039        /*
     1040         * Ignore localhost as hostname (it's implicit).
     1041         */
     1042        static char const s_szLocalhost[] = "localhost";
     1043        if (    Parsed.cchAuthorityHost == sizeof(s_szLocalhost) - 1U
     1044            &&  RTStrNICmp(&pszUri[Parsed.offAuthorityHost], RT_STR_TUPLE(s_szLocalhost)) == 0)
     1045        {
     1046            Parsed.cchAuthorityHost = 0;
     1047            Parsed.cchAuthority     = 0;
     1048        }
     1049
     1050        /*
     1051         * Ignore leading path slash/separator if we detect a DOS drive letter
     1052         * and we don't have a host name.
     1053         */
     1054        if (   Parsed.cchPath >= 3
     1055            && Parsed.cchAuthorityHost    == 0
     1056            && pszUri[Parsed.offPath]     == '/'           /* Leading path slash/separator. */
     1057            && (   pszUri[Parsed.offPath + 2] == ':'       /* Colon after drive letter. */
     1058                || pszUri[Parsed.offPath + 2] == '|')      /* Colon alternative. */
     1059            && RT_C_IS_ALPHA(pszUri[Parsed.offPath + 1]) ) /* Drive letter. */
     1060        {
     1061            Parsed.offPath++;
     1062            Parsed.cchPath--;
     1063        }
     1064
    8791065        /*
    8801066         * Calculate the size of the encoded result.
     1067         *
     1068         * Since we're happily returning "C:/Windows/System32/kernel.dll"
     1069         * style paths when the caller requested UNIX style paths, we will
     1070         * return straight UNC paths too ("//cifsserver/share/dir/file").
    8811071         */
    882         size_t cbResult = 0;
    883 
    884         /* Skip the leading slash if a DOS drive letter (e.g. "C:") is detected right after it. */
    885         if (   Parsed.cchPath >= 3
    886             && pszUri[Parsed.offPath]  == '/'        /* Leading slash. */
    887             && RT_C_IS_ALPHA(pszUri[Parsed.offPath + 1]) /* Drive letter. */
    888             && pszUri[Parsed.offPath + 2]  == ':')
    889         {
    890             Parsed.offPath++;
    891             Parsed.cchPath--;
    892         }
    893 
    894         /* Windows: Authority given? Include authority as part of UNC path */
    895         if (uFormat == URI_FILE_FORMAT_WIN && Parsed.cchAuthority)
    896         {
    897             cbResult += 2; /* UNC slashes "\\". */
    898             cbResult += Parsed.cchAuthority;
    899         }
    900 
    901         cbResult += Parsed.cchPath;
    902         cbResult += 1; /* Zero termination. */
    903 
    904         /*
    905          * Compose encoded string.
    906          */
    907         char *pszResult;
    908         char *pszTmp = pszResult = RTStrAlloc(cbResult);
    909         if (pszTmp)
    910         {
    911             size_t cbTmp = cbResult;
    912 
    913             /* Windows: If an authority is given, add the required UNC prefix. */
    914             if (uFormat == URI_FILE_FORMAT_WIN && Parsed.cchAuthority)
    915             {
    916                 rc = RTStrCatP(&pszTmp, &cbTmp, "\\\\");
     1072        size_t cchDecodedHost = 0;
     1073        size_t cbResult;
     1074        if (Parsed.fFlags & RTURIPARSED_F_CONTAINS_ESCAPED_CHARS)
     1075        {
     1076            cchDecodedHost = rtUriCalcDecodedLength(&pszUri[Parsed.offAuthorityHost], Parsed.cchAuthorityHost);
     1077            cbResult = cchDecodedHost + rtUriCalcDecodedLength(&pszUri[Parsed.offPath], Parsed.cchPath) + 1;
     1078        }
     1079        else
     1080        {
     1081            cchDecodedHost = 0;
     1082            cbResult = Parsed.cchAuthorityHost + Parsed.cchPath + 1;
     1083        }
     1084        if (pcchPath)
     1085            *pcchPath = cbResult - 1;
     1086        if (cbResult > 1)
     1087        {
     1088            /*
     1089             * Prepare the necessary buffer space for the result.
     1090             */
     1091            char  *pszDst;
     1092            char  *pszFreeMe = NULL;
     1093            if (!cbPath || *ppszPath == NULL)
     1094            {
     1095                cbPath = RT_MAX(cbPath, cbResult);
     1096                *ppszPath = pszFreeMe = pszDst = RTStrAlloc(cbPath);
     1097                AssertReturn(pszDst, VERR_NO_STR_MEMORY);
     1098            }
     1099            else if (cbResult <= cbPath)
     1100                pszDst = *ppszPath;
     1101            else
     1102                return VERR_BUFFER_OVERFLOW;
     1103
     1104            /*
     1105             * Compose the result.
     1106             */
     1107            if (Parsed.fFlags & RTURIPARSED_F_CONTAINS_ESCAPED_CHARS)
     1108            {
     1109                rc = rtUriDecodeIntoBuffer(&pszUri[Parsed.offAuthorityHost],Parsed.cchAuthorityHost,
     1110                                           pszDst, cchDecodedHost + 1);
     1111                Assert(RT_SUCCESS(rc) && strlen(pszDst) == cchDecodedHost);
    9171112                if (RT_SUCCESS(rc))
    918                     rc = RTStrCatPEx(&pszTmp, &cbTmp, &pszUri[Parsed.offAuthority], Parsed.cchAuthority);
     1113                    rc = rtUriDecodeIntoBuffer(&pszUri[Parsed.offPath], Parsed.cchPath,
     1114                                               &pszDst[cchDecodedHost], cbResult - cchDecodedHost);
     1115                Assert(RT_SUCCESS(rc) && strlen(pszDst) == cbResult - 1);
     1116            }
     1117            else
     1118            {
     1119                memcpy(pszDst, &pszUri[Parsed.offAuthorityHost], Parsed.cchAuthorityHost);
     1120                memcpy(&pszDst[Parsed.cchAuthorityHost], &pszUri[Parsed.offPath], Parsed.cchPath);
     1121                pszDst[cbResult - 1] = '\0';
    9191122            }
    9201123            if (RT_SUCCESS(rc))
    921                 rc = RTStrCatPEx(&pszTmp, &cbTmp, &pszUri[Parsed.offPath], Parsed.cchPath);
    922             AssertRC(rc); /* Shall not happen! */
    923             if (RT_SUCCESS(rc))
    9241124            {
    9251125                /*
    926                  * Decode the string and switch the slashes around the request way before returning.
     1126                 * Convert colon DOS driver letter colon alternative.
     1127                 * We do this regardless of the desired path style.
    9271128                 */
    928                 char *pszPath = rtUriPercentDecodeN(pszResult, cbResult - 1 /* Minus termination */);
    929                 if (pszPath)
    930                 {
    931                     RTStrFree(pszResult);
    932 
    933                     if (uFormat == URI_FILE_FORMAT_UNIX)
    934                         return RTPathChangeToUnixSlashes(pszPath, true);
    935                     Assert(uFormat == URI_FILE_FORMAT_WIN);
    936                     return RTPathChangeToDosSlashes(pszPath, true);
    937                 }
    938 
    939                 /* Failed. */
     1129                if (   RT_C_IS_ALPHA(pszDst[0])
     1130                    && pszDst[1] == '|')
     1131                    pszDst[1] = ':';
     1132
     1133                /*
     1134                 * Fix slashes.
     1135                 */
     1136                if (fPathStyle == RTPATH_STR_F_STYLE_DOS)
     1137                    RTPathChangeToDosSlashes(pszDst, true);
     1138                else if (fPathStyle == RTPATH_STR_F_STYLE_UNIX)
     1139                    RTPathChangeToUnixSlashes(pszDst, true); /** @todo not quite sure how this actually makes sense... */
     1140                else
     1141                    AssertFailed();
     1142                return rc;
    9401143            }
    941             RTStrFree(pszResult);
    942         }
    943     }
     1144
     1145            /* bail out */
     1146            RTStrFree(pszFreeMe);
     1147        }
     1148        else
     1149            rc = VERR_PATH_ZERO_LENGTH;
     1150    }
     1151    return rc;
     1152}
     1153
     1154
     1155RTDECL(char *) RTUriFilePath(const char *pszUri, uint32_t uFormat)
     1156{
     1157    uint32_t fPathStyle;
     1158    switch (uFormat)
     1159    {
     1160        case URI_FILE_FORMAT_WIN:  fPathStyle = RTPATH_STR_F_STYLE_DOS; break;
     1161        case URI_FILE_FORMAT_UNIX: fPathStyle = RTPATH_STR_F_STYLE_UNIX; break;
     1162        case URI_FILE_FORMAT_AUTO: fPathStyle = RTPATH_STR_F_STYLE_HOST; break;
     1163        default: AssertFailedReturn(NULL);
     1164    }
     1165
     1166    char *pszPath = NULL;
     1167    int rc = RTUriFilePathEx(pszUri, fPathStyle, &pszPath, 0 /*cbPath*/, NULL /*pcchPath*/);
     1168    if (RT_SUCCESS(rc))
     1169        return pszPath;
    9441170    return NULL;
    9451171}
    9461172
     1173
  • trunk/src/VBox/Runtime/testcase/tstRTUri.cpp

    r58067 r58068  
    305305{
    306306    const char     *pszPath;
     307    uint32_t        fPathPathStyle;
    307308    const char     *pszUri;
    308309    uint32_t        uFormat;
     
    313314    {   /* #0: */
    314315        /* .pszPath          =*/ "C:\\over\\ <>#%\"{}|^[]`\\there",
     316        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    315317        /* .pszUri           =*/ "file:///C:%5Cover/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60%5Cthere",
    316318        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    322324    {   /* #1: */
    323325        /* .pszPath          =*/ "/over/ <>#%\"{}|^[]`/there",
     326        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_UNIX,
    324327        /* .pszUri           =*/ "file:///over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there",
    325328        /* .uFormat          =*/ URI_FILE_FORMAT_UNIX,
     
    331334    {   /* #2: */
    332335        /* .pszPath          =*/ NULL,
     336        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_UNIX,
    333337        /* .pszUri           =*/ "file://",
    334338        /* .uFormat          =*/ URI_FILE_FORMAT_UNIX,
     
    340344    {   /* #3: */
    341345        /* .pszPath          =*/ NULL,
     346        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    342347        /* .pszUri           =*/ "file://",
    343348        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    349354    {   /* #4: */
    350355        /* .pszPath          =*/ "/",
     356        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_UNIX,
    351357        /* .pszUri           =*/ "file:///",
    352358        /* .uFormat          =*/ URI_FILE_FORMAT_UNIX,
     
    358364    {   /* #5: */
    359365        /* .pszPath          =*/ "\\",
     366        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    360367        /* .pszUri           =*/ "file:///",
    361368        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    367374    {   /* #6: */
    368375        /* .pszPath          =*/ "/foo/bar",
     376        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_UNIX,
    369377        /* .pszUri           =*/ "file:///foo/bar",
    370378        /* .uFormat          =*/ URI_FILE_FORMAT_UNIX,
     
    376384    {   /* #7: */
    377385        /* .pszPath          =*/ "\\foo\\bar",
     386        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    378387        /* .pszUri           =*/ "file:///foo%5Cbar",
    379388        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    385394    {   /* #8: */
    386395        /* .pszPath          =*/ "C:/over/ <>#%\"{}|^[]`/there",
     396        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_UNIX,
    387397        /* .pszUri           =*/ "file:///C:/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there",
    388398        /* .uFormat          =*/ URI_FILE_FORMAT_UNIX,
     
    394404    {   /* #9: */
    395405        /* .pszPath          =*/ "\\over\\ <>#%\"{}|^[]`\\there",
     406        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    396407        /* .pszUri           =*/ "file:///over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there",
    397408        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    403414    {   /* #10: */
    404415        /* .pszPath          =*/ "/usr/bin/grep",
     416        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_UNIX,
    405417        /* .pszUri           =*/ "file:///usr/bin/grep",
    406418        /* .uFormat          =*/ URI_FILE_FORMAT_UNIX,
     
    412424    {   /* #11: */
    413425        /* .pszPath          =*/ "\\usr\\bin\\grep",
     426        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    414427        /* .pszUri           =*/ "file:///usr/bin/grep",
    415428        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    421434    {   /* #12: */
    422435        /* .pszPath          =*/ "/somerootsubdir/isos/files.lst",
     436        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_UNIX,
    423437        /* .pszUri           =*/ "file:///somerootsubdir/isos/files.lst",
    424438        /* .uFormat          =*/ URI_FILE_FORMAT_UNIX,
     
    430444    {   /* #13: */
    431445        /* .pszPath          =*/ "\\not-a-cifsserver\\isos\\files.lst",
     446        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    432447        /* .pszUri           =*/ "file:///not-a-cifsserver/isos/files.lst",
    433448        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    439454    {   /* #14: */
    440455        /* .pszPath          =*/ "/rootsubdir/isos/files.lst",
     456        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_UNIX,
    441457        /* .pszUri           =*/ "file:///rootsubdir/isos/files.lst",
    442458        /* .uFormat          =*/ URI_FILE_FORMAT_UNIX,
     
    448464    {   /* #15: */
    449465        /* .pszPath          =*/ "\\not-a-cifsserver-either\\isos\\files.lst",
     466        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    450467        /* .pszUri           =*/ "file:///not-a-cifsserver-either/isos/files.lst",
    451468        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    457474    {   /* #16: */
    458475        /* .pszPath          =*/ "\\\\cifsserver\\isos\\files.lst",
     476        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    459477        /* .pszUri           =*/ "file:////cifsserver/isos/files.lst",
    460478        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    466484    {   /* #17: */
    467485        /* .pszPath          =*/ "c:boot.ini",
     486        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    468487        /* .pszUri           =*/ "file://localhost/c:boot.ini",
    469488        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    475494    {   /* #18: */
    476495        /* .pszPath          =*/ "c:boot.ini",
     496        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
    477497        /* .pszUri           =*/ "file:///c|boot.ini",
    478498        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     
    481501        /* PathCreateFromUrl =   "c:boot.ini" - same */
    482502        /* UrlCreateFromPath =   "file:///c:boot.ini" - same */
     503    },
     504    {   /* #19: */
     505        /* .pszPath          =*/ "c:\\legacy-no-slash.ini",
     506        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     507        /* .pszUri           =*/ "file:c:\\legacy-no-slash%2Eini",
     508        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     509        /* .pszCreatedPath   =*/ "c:\\legacy-no-slash.ini",
     510        /* .pszCreatedUri    =*/ "file:///c:/legacy-no-slash.ini",
     511        /* PathCreateFromUrl =   "c:\\legacy-no-slash.ini" - same */
     512        /* UrlCreateFromPath =   "file:///c:/legacy-no-slash.ini" - same */
     513    },
     514    {   /* #20: */
     515        /* .pszPath          =*/ "c:\\legacy-no-slash.ini",
     516        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     517        /* .pszUri           =*/ "file:c|\\legacy-no-slash%2Eini",
     518        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     519        /* .pszCreatedPath   =*/ "c:\\legacy-no-slash.ini",
     520        /* .pszCreatedUri    =*/ "file:///c:/legacy-no-slash.ini",
     521        /* PathCreateFromUrl =   "c:\\legacy-no-slash.ini" - same */
     522        /* UrlCreateFromPath =   "file:///c:/legacy-no-slash.ini" - same */
     523    },
     524    {   /* #21: */
     525        /* .pszPath          =*/ "c:\\legacy-single-slash.ini",
     526        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     527        /* .pszUri           =*/ "file:/c:\\legacy-single-slash%2Eini",
     528        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     529        /* .pszCreatedPath   =*/ "c:\\legacy-single-slash.ini",
     530        /* .pszCreatedUri    =*/ "file:///c:/legacy-single-slash.ini",
     531        /* PathCreateFromUrl =   "c:\\legacy-single-slash.ini" - same */
     532        /* UrlCreateFromPath =   "file:///c:/legacy-single-slash.ini" - same */
     533    },
     534    {   /* #22: */
     535        /* .pszPath          =*/ "c:\\legacy-single-slash.ini",
     536        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     537        /* .pszUri           =*/ "file:/c:\\legacy-single-slash%2Eini",
     538        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     539        /* .pszCreatedPath   =*/ "c:\\legacy-single-slash.ini",
     540        /* .pszCreatedUri    =*/ "file:///c:/legacy-single-slash.ini",
     541        /* PathCreateFromUrl =   "c:\\legacy-single-slash.ini" - same */
     542        /* UrlCreateFromPath =   "file:///c:/legacy-single-slash.ini" - same */
     543    },
     544    {   /* #23: */
     545        /* .pszPath          =*/ "\\legacy-single-slash.ini",
     546        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     547        /* .pszUri           =*/ "file:/legacy-single-slash%2Eini",
     548        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     549        /* .pszCreatedPath   =*/ "\\legacy-single-slash.ini",
     550        /* .pszCreatedUri    =*/ "file:///legacy-single-slash.ini",
     551        /* PathCreateFromUrl =   "\\legacy-single-slash.ini" - same */
     552        /* UrlCreateFromPath =   "file:///legacy-single-slash.ini" - same */
     553    },
     554    {   /* #24: */
     555        /* .pszPath          =*/ "C:\\legacy-double-slash%2E.ini",
     556        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     557        /* .pszUri           =*/ "file://C:\\legacy-double-slash%2E.ini",
     558        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     559        /* .pszCreatedPath   =*/ "C:\\legacy-double-slash%2E.ini",
     560        /* .pszCreatedUri    =*/ "file:///C:/legacy-double-slash%252E.ini",
     561        /* PathCreateFromUrl =   "C:\\legacy-double-slash%2E.ini" - same */
     562        /* UrlCreateFromPath =   "file:///C:/legacy-double-slash.ini" - same */
     563    },
     564    {   /* #25: */
     565        /* .pszPath          =*/ "C:\\legacy-double-slash%2E.ini",
     566        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     567        /* .pszUri           =*/ "file://C|/legacy-double-slash%2E.ini",
     568        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     569        /* .pszCreatedPath   =*/ "C:\\legacy-double-slash%2E.ini",
     570        /* .pszCreatedUri    =*/ "file:///C:/legacy-double-slash%252E.ini",
     571        /* PathCreateFromUrl =   "C:\\legacy-double-slash%2E.ini" - same */
     572        /* UrlCreateFromPath =   "file:///C:/legacy-double-slash%252E.ini" - same */
     573    },
     574    {   /* #26: */
     575        /* .pszPath          =*/ "C:\\legacy-4-slashes%2E.ini",
     576        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     577        /* .pszUri           =*/ "file:////C|/legacy-4-slashes%2E.ini",
     578        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     579        /* .pszCreatedPath   =*/ "C:\\legacy-4-slashes%2E.ini",
     580        /* .pszCreatedUri    =*/ "file:///C:/legacy-4-slashes%252E.ini",
     581        /* PathCreateFromUrl =   "C:\\legacy-4-slashes%2E.ini" - same */
     582        /* UrlCreateFromPath =   "file:///C:/legacy-4-slashes%252E.ini" - same */
     583    },
     584    {   /* #27: */
     585        /* .pszPath          =*/ "C:\\legacy-4-slashes%2E.ini",
     586        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     587        /* .pszUri           =*/ "file:////C:/legacy-4-slashes%2E.ini",
     588        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     589        /* .pszCreatedPath   =*/ "C:\\legacy-4-slashes%2E.ini",
     590        /* .pszCreatedUri    =*/ "file:///C:/legacy-4-slashes%252E.ini",
     591        /* PathCreateFromUrl =   "C:\\legacy-4-slashes%2E.ini" - same */
     592        /* UrlCreateFromPath =   "file:///C:/legacy-4-slashes%252E.ini" - same */
     593    },
     594    {   /* #28: */
     595        /* .pszPath          =*/ "\\\\cifsserver\\share\\legacy-4-slashes%2E.ini",
     596        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     597        /* .pszUri           =*/ "file:////cifsserver/share/legacy-4-slashes%2E.ini",
     598        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     599        /* .pszCreatedPath   =*/ "\\\\cifsserver\\share\\legacy-4-slashes%2E.ini",
     600        /* .pszCreatedUri    =*/ "file://cifsserver/share/legacy-4-slashes%252E.ini",
     601        /* PathCreateFromUrl =   "\\\\cifsserver\\share\\legacy-4-slashes%2E.ini" - same */
     602        /* UrlCreateFromPath =   "file://cifsserver/share/legacy-4-slashes%252E.ini" - same */
     603    },
     604    {   /* #29: */
     605        /* .pszPath          =*/ "\\\\cifsserver\\share\\legacy-5-slashes.ini",
     606        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     607        /* .pszUri           =*/ "file://///cifsserver/share/legacy-5-slashes%2Eini",
     608        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     609        /* .pszCreatedPath   =*/ "\\\\cifsserver\\share\\legacy-5-slashes.ini",
     610        /* .pszCreatedUri    =*/ "file://cifsserver/share/legacy-5-slashes.ini",
     611        /* PathCreateFromUrl =   "\\\\cifsserver\\share\\legacy-5-slashes.ini" - same */
     612        /* UrlCreateFromPath =   "file://cifsserver/share/legacy-5-slashes.ini" - same */
     613    },
     614    {   /* #30: */
     615        /* .pszPath          =*/ "\\\\C|\\share\\legacy-5-slashes.ini",
     616        /* .fPathPathStyle   =*/ RTPATH_STR_F_STYLE_DOS,
     617        /* .pszUri           =*/ "file://///C|/share/legacy-5-slashes%2Eini",
     618        /* .uFormat          =*/ URI_FILE_FORMAT_WIN,
     619        /* .pszCreatedPath   =*/ "\\\\C|\\share\\legacy-5-slashes.ini",
     620        /* .pszCreatedUri    =*/ "file://C%7C/share/legacy-5-slashes.ini",
     621        /* PathCreateFromUrl =   "\\\\C|\\share\\legacy-5-slashes.ini" - same */
     622        /* UrlCreateFromPath =   "file:///C%7C/share/legacy-5-slashes.ini" - differs */
    483623    },
    484624};
     
    585725            WCHAR wszResult2[_1K];
    586726            DWORD cwcResult2 = RT_ELEMENTS(wszResult2);
    587             hrc = UrlEscapeW(wszResult, wszResult2, &cwcResult2, URL_DONT_ESCAPE_EXTRA_INFO );
     727            hrc = UrlEscapeW(wszResult, wszResult2, &cwcResult2, URL_DONT_ESCAPE_EXTRA_INFO | URL_ESCAPE_AS_UTF8 );
    588728            if (SUCCEEDED(hrc))
    589729            {
     
    616756    for (size_t i = 0; i < RT_ELEMENTS(g_aCreateFileURIs); ++i)
    617757    {
    618         uint32_t const fPathStyle = g_aCreateFileURIs[i].uFormat == URI_FILE_FORMAT_WIN
    619                                   ? RTPATH_STR_F_STYLE_DOS : RTPATH_STR_F_STYLE_UNIX;
     758        uint32_t const     fPathStyle = g_aCreateFileURIs[i].fPathPathStyle;
     759        const char * const pszPath    = g_aCreateFileURIs[i].pszPath;
    620760        char *pszUri = (char *)&pszUri;
    621         int rc = RTUriFileCreateEx(g_aCreateFileURIs[i].pszPath, fPathStyle, &pszUri, 0, NULL);
     761        int rc = RTUriFileCreateEx(pszPath, fPathStyle, &pszUri, 0, NULL);
    622762        if (RT_SUCCESS(rc))
    623763        {
     
    629769                }
    630770                else
    631                     RTTestIFailed("#%u: '%s'/%#x => '%s', expected '%s'", i,
    632                                   g_aCreateFileURIs[i].pszPath, fPathStyle,
    633                                   pszUri, g_aCreateFileURIs[i].pszCreatedUri);
     771                    RTTestIFailed("#%u: '%s'/%#x => '%s', expected '%s'",
     772                                  i, pszPath, fPathStyle, pszUri, g_aCreateFileURIs[i].pszCreatedUri);
    634773            }
    635774            else
    636775                RTTestIFailed("#%u: bad testcase; pszCreatedUri is NULL\n", i);
    637776        }
    638         else if (rc != VERR_INVALID_POINTER || g_aCreateFileURIs[i].pszPath != NULL)
    639             RTTestIFailed("#%u: '%s'/%#x => %Rrc", i, g_aCreateFileURIs[i].pszPath, fPathStyle, rc);
     777        else if (rc != VERR_INVALID_POINTER || pszPath != NULL)
     778            RTTestIFailed("#%u: '%s'/%#x => %Rrc", i, pszPath, fPathStyle, rc);
    640779    }
    641780}
     
    702841    /* File Uri path */
    703842    RTTestISub("RTUriFilePath");
    704     for (size_t i = 0; i < RT_ELEMENTS(g_aCreateFileURIs) - 3; ++i) /** @todo r=bird: Fixed last three tests in RTUriFilePath */
     843    for (size_t i = 0; i < RT_ELEMENTS(g_aCreateFileURIs); ++i)
    705844        CHECK_STR_API(RTUriFilePath(g_aCreateFileURIs[i].pszUri, g_aCreateFileURIs[i].uFormat),
    706845                      g_aCreateFileURIs[i].pszCreatedPath);
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