VirtualBox

Ignore:
Timestamp:
Oct 1, 2015 11:20:52 AM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
102993
Message:

IPRT: misc/uri.cpp: Bugfixes, behave more like PathCreateFromUrl/UrlCreateFromPath on Windows. Added a couple more tests.

File:
1 edited

Legend:

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

    r57825 r57981  
    4848    foo://example.com:8042/over/there?name=ferret#nose
    4949    \_/   \______________/\_________/ \_________/ \__/
    50      |           |            |            |        |
     50     |           |             |           |        |
    5151  scheme     authority       path        query   fragment
    5252     |   _____________________|__
     
    121121static char *rtUriPercentDecodeN(const char *pszString, size_t cchString)
    122122{
    123     AssertPtr(pszString);
    124     Assert(strlen(pszString) >= cchString);
     123    AssertPtrReturn(pszString, NULL);
     124    AssertReturn(strlen(pszString) >= cchString, NULL);
    125125
    126126    /*
     
    478478
    479479
    480 
    481480RTDECL(int) RTUriParse(const char *pszUri, PRTURIPARSED pParsed)
    482481{
     
    683682    if (pszPath)
    684683    {
    685         /* Create the percent encoded strings and calculate the necessary uri length. */
     684        /* Check if it's an UNC path. Skip any leading slashes. */
     685        while (pszPath)
     686        {
     687            if (   *pszPath != '\\'
     688                && *pszPath != '/')
     689                break;
     690            pszPath++;
     691        }
     692
     693        /* Create the percent encoded strings and calculate the necessary URI length. */
    686694        char *pszPath1 = rtUriPercentEncodeN(pszPath, RTSTR_MAX);
    687695        if (pszPath1)
    688696        {
     697            /* Always change DOS slashes to Unix slashes. */
     698            RTPathChangeToUnixSlashes(pszPath1, true); /** @todo Flags? */
     699
    689700            size_t cbSize = 7 /* file:// */ + strlen(pszPath1) + 1; /* plus zero byte */
    690701            if (pszPath1[0] != '/')
     
    693704            if (pszResult)
    694705            {
    695                 /* Compose the target uri string. */
     706                /* Compose the target URI string. */
    696707                *pszTmp = '\0';
    697708                RTStrCatP(&pszTmp, &cbSize, "file://");
     
    703714        }
    704715    }
     716    else
     717    {
     718        char *pszResTmp;
     719        int cchRes = RTStrAPrintf(&pszResTmp, "file://");
     720        if (cchRes)
     721            pszResult = pszResTmp;
     722    }
     723
    705724    return pszResult;
    706725}
     
    726745#endif
    727746
    728     /* Check that this is a file Uri */
     747    /* Check that this is a file URI. */
    729748    if (RTStrNICmp(pszUri, RT_STR_TUPLE("file:")) != 0)
    730749        return NULL;
     
    732751    RTURIPARSED Parsed;
    733752    int rc = rtUriParse(pszUri, &Parsed);
    734     if (RT_SUCCESS(rc) && Parsed.cchPath)
    735     {
    736         /* Special hack for DOS path like file:///c:/WINDOWS/clock.avi where we
    737            have to drop the leading slash that was used to separate the authority
    738            from the path. */
    739         if (  uFormat == URI_FILE_FORMAT_WIN
    740             && Parsed.cchPath >= 3
    741             && pszUri[Parsed.offPath] == '/'
    742             && pszUri[Parsed.offPath + 2] == ':'
    743             && RT_C_IS_ALPHA(pszUri[Parsed.offPath + 1]) )
     753    if (RT_SUCCESS(rc))
     754    {
     755        /* No path detected? Take authority as path then. */
     756        if (!Parsed.cchPath)
     757        {
     758            Parsed.cchPath      = Parsed.cchAuthority;
     759            Parsed.offPath      = Parsed.offAuthority;
     760            Parsed.cchAuthority = 0;
     761        }
     762    }
     763
     764    if (   RT_SUCCESS(rc)
     765        && Parsed.cchPath)
     766    {
     767        const char *pszPathOff = &pszUri[Parsed.offPath];
     768        size_t cbResult = 0;
     769
     770        /* Skip the leading slash if a DOS drive letter (e.g. "C:") is detected right after it. */
     771        if (   Parsed.cchPath >= 3
     772            && pszPathOff[0]  == '/'        /* Leading slash. */
     773            && RT_C_IS_ALPHA(pszPathOff[1]) /* Drive letter. */
     774            && pszPathOff[2]  == ':')
    744775        {
    745776            Parsed.offPath++;
    746777            Parsed.cchPath--;
    747         }
    748 
    749         char *pszPath = rtUriPercentDecodeN(&pszUri[Parsed.offPath], Parsed.cchPath);
    750         if (uFormat == URI_FILE_FORMAT_UNIX)
    751             return RTPathChangeToUnixSlashes(pszPath, true);
    752         Assert(uFormat == URI_FILE_FORMAT_WIN);
    753         return RTPathChangeToDosSlashes(pszPath, true);
    754     }
     778            pszPathOff++;
     779        }
     780
     781        if (uFormat == URI_FILE_FORMAT_WIN)
     782        {
     783            /* Authority given? */
     784            if (Parsed.cchAuthority)
     785            {
     786                /* Include authority as part of UNC path. */
     787                cbResult += 2; /* UNC slashes "\\". */
     788                cbResult += Parsed.cchAuthority;
     789            }
     790        }
     791
     792        cbResult += Parsed.cchPath;
     793        cbResult += 1; /* Zero termination. */
     794
     795        /*
     796         * Compose string.
     797         */
     798        int rc = VINF_SUCCESS;
     799        char *pszResult;
     800
     801        do
     802        {
     803            char *pszTmp = pszResult = RTStrAlloc(cbResult);
     804            if (pszTmp)
     805            {
     806                size_t cbTmp = cbResult;
     807
     808                if (uFormat == URI_FILE_FORMAT_WIN)
     809                {
     810                    /* If an authority is given, add the required UNC prefix. */
     811                    if (Parsed.cchAuthority)
     812                    {
     813                        rc = RTStrCatP(&pszTmp, &cbTmp, "\\\\");
     814                        if (RT_SUCCESS(rc))
     815                            rc = RTStrCatPEx(&pszTmp, &cbTmp, &pszUri[Parsed.offAuthority], Parsed.cchAuthority);
     816                    }
     817                    else
     818                    {
     819
     820                    }
     821                }
     822
     823                if (RT_SUCCESS(rc))
     824                    rc = RTStrCatPEx(&pszTmp, &cbTmp, &pszUri[Parsed.offPath], Parsed.cchPath);
     825
     826                if (RT_FAILURE(rc))
     827                    RTStrFree(pszResult);
     828            }
     829            else
     830                rc = VERR_NO_MEMORY;
     831
     832        } while (0);
     833
     834        if (RT_SUCCESS(rc))
     835        {
     836            AssertPtr(pszResult);
     837            Assert(cbResult);
     838            char *pszPath = rtUriPercentDecodeN(pszResult, cbResult - 1 /* Minus termination */);
     839            RTStrFree(pszResult);
     840            if (uFormat == URI_FILE_FORMAT_UNIX)
     841                return RTPathChangeToUnixSlashes(pszPath, true);
     842            Assert(uFormat == URI_FILE_FORMAT_WIN);
     843            return RTPathChangeToDosSlashes(pszPath, true);
     844        }
     845    }
     846
    755847    return NULL;
    756848}
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