diff options
author | sb <sb@openoffice.org> | 2011-05-12 17:53:15 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2011-05-20 10:32:03 +0100 |
commit | 8c015fbb85f00fe1cc82e00ea1771ad9fba821d2 (patch) | |
tree | f55f4486cd76ccecd8bc78ee27d4e15fa089ed96 /sal/osl | |
parent | f85638485cdc1ddd25f322ea4c30a386351f4bd5 (diff) |
#i116915# rewrote unx osl_getSystemPathFromFileURL to avoid mem leaks
Diffstat (limited to 'sal/osl')
-rw-r--r-- | sal/osl/unx/file_url.cxx | 211 | ||||
-rw-r--r-- | sal/osl/unx/makefile.mk | 1 | ||||
-rw-r--r-- | sal/osl/w32/file_url.cxx | 5 |
3 files changed, 83 insertions, 134 deletions
diff --git a/sal/osl/unx/file_url.cxx b/sal/osl/unx/file_url.cxx index ab6c9d664811..0e98b2e14c08 100644 --- a/sal/osl/unx/file_url.cxx +++ b/sal/osl/unx/file_url.cxx @@ -39,12 +39,12 @@ #include <unistd.h> #include "osl/file.hxx" -#include <osl/security.h> +#include <osl/security.hxx> #include <osl/diagnose.h> #include <osl/thread.h> #include <osl/process.h> -#include <rtl/uri.h> +#include <rtl/uri.hxx> #include <rtl/ustring.hxx> #include <rtl/ustrbuf.h> #include "rtl/textcvt.h" @@ -148,153 +148,96 @@ oslFileError SAL_CALL osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uStrin /* osl_getSystemPathFromFileURL */ /****************************************************************************/ -oslFileError SAL_CALL osl_getSystemPathFromFileURL( rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath ) -{ - sal_Int32 nIndex; - rtl_uString * pTmp = NULL; - - sal_Unicode encodedSlash[3] = { '%', '2', 'F' }; - sal_Unicode protocolDelimiter[3] = { ':', '/', '/' }; +namespace { - /* temporary hack: if already system path, return ustrFileURL */ - /* - if( (sal_Unicode) '/' == ustrFileURL->buffer[0] ) - { - OSL_FAIL( "osl_getSystemPathFromFileURL: input is already system path" ); - rtl_uString_assign( pustrSystemPath, ustrFileURL ); - return osl_File_E_None; - } - */ - - /* a valid file url may not start with '/' */ - if( ( 0 == ustrFileURL->length ) || ( (sal_Unicode) '/' == ustrFileURL->buffer[0] ) ) - { - return osl_File_E_INVAL; - } - - /* Check for non file:// protocols */ - - nIndex = rtl_ustr_indexOfStr_WithLength( ustrFileURL->buffer, ustrFileURL->length, protocolDelimiter, 3 ); - if ( -1 != nIndex && (4 != nIndex || 0 != rtl_ustr_ascii_shortenedCompare_WithLength( ustrFileURL->buffer, ustrFileURL->length,"file", 4 ) ) ) - { - return osl_File_E_INVAL; - } - - /* search for encoded slashes (%2F) and decode every single token if we find one */ - - nIndex = 0; +oslFileError getSystemPathFromFileUrl( + rtl::OUString const & url, rtl::OUString * path, bool homeAbbreviation) +{ + OSL_ASSERT(path != 0 && path->getLength() == 0); - if( -1 != rtl_ustr_indexOfStr_WithLength( ustrFileURL->buffer, ustrFileURL->length, encodedSlash, 3 ) ) - { - rtl_uString * ustrPathToken = NULL; - sal_Int32 nOffset = 7; + sal_Unicode const * p = url.getStr(); + sal_Unicode const * end = p + url.getLength(); - do + for (sal_Unicode const * p1 = p; p1 != end; ++p1) { + if (*p1 == '?' || *p1 == '#' || + (*p1 == '%' && end - p1 >= 3 && p1[1] == '2' && + (p1[2] == 'F' || p1[2] == 'f'))) { - nOffset += nIndex; - - /* break url down in '/' devided tokens tokens */ - nIndex = rtl_ustr_indexOfChar_WithLength( ustrFileURL->buffer + nOffset, ustrFileURL->length - nOffset, (sal_Unicode) '/' ); - - /* copy token to new string */ - rtl_uString_newFromStr_WithLength( &ustrPathToken, ustrFileURL->buffer + nOffset, - -1 == nIndex ? ustrFileURL->length - nOffset : nIndex++ ); - - /* decode token */ - rtl_uriDecode( ustrPathToken, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8, &pTmp ); - - /* the result should not contain any '/' */ - if( -1 != rtl_ustr_indexOfChar_WithLength( pTmp->buffer, pTmp->length, (sal_Unicode) '/' ) ) - { - rtl_uString_release( pTmp ); - rtl_uString_release( ustrPathToken ); - - return osl_File_E_INVAL; - } - - } while( -1 != nIndex ); - - /* release temporary string and restore index variable */ - rtl_uString_release( ustrPathToken ); - nIndex = 0; + return osl_File_E_INVAL; + } } - - /* protocol and server should not be encoded, so decode the whole string */ - rtl_uriDecode( ustrFileURL, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8, &pTmp ); - - /* check if file protocol specified */ - /* FIXME: use rtl_ustr_ascii_shortenedCompareIgnoreCase_WithLength when available */ - if( 7 <= pTmp->length ) - { - rtl_uString * pProtocol = NULL; - rtl_uString_newFromStr_WithLength( &pProtocol, pTmp->buffer, 7 ); - - /* protocol is case insensitive */ - rtl_ustr_toAsciiLowerCase_WithLength( pProtocol->buffer, pProtocol->length ); - - if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pProtocol->buffer, pProtocol->length,"file://", 7 ) ) - nIndex = 7; - - rtl_uString_release( pProtocol ); + sal_Unicode const * p1 = p; + while (p1 != end && *p1 != ':' && *p1 != '/') { + ++p1; } - - /* skip "localhost" or "127.0.0.1" if "file://" is specified */ - /* FIXME: use rtl_ustr_ascii_shortenedCompareIgnoreCase_WithLength when available */ - if( nIndex && ( 10 <= pTmp->length - nIndex ) ) - { - rtl_uString * pServer = NULL; - rtl_uString_newFromStr_WithLength( &pServer, pTmp->buffer + nIndex, 10 ); - - /* server is case insensitive */ - rtl_ustr_toAsciiLowerCase_WithLength( pServer->buffer, pServer->length ); - - if( ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pServer->buffer, pServer->length,"localhost/", 10 ) ) || - ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pServer->buffer, pServer->length,"127.0.0.1/", 10 ) ) ) + if (p1 != end && *p1 == ':') { + if (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( + p, p1 - p, RTL_CONSTASCII_STRINGPARAM("file")) != + 0) { - /* don't exclude the '/' */ - nIndex += 9; + return osl_File_E_INVAL; } - - rtl_uString_release( pServer ); + p = p1 + 1; } - - if( nIndex ) - rtl_uString_newFromStr_WithLength( &pTmp, pTmp->buffer + nIndex, pTmp->length - nIndex ); - - /* check if system path starts with ~ or ~user and replace it with the appropriate home dir */ - if( (sal_Unicode) '~' == pTmp->buffer[0] ) - { - /* check if another user is specified */ - if( ( 1 == pTmp->length ) || ( (sal_Unicode)'/' == pTmp->buffer[1] ) ) - { - rtl_uString *pTmp2 = NULL; - - /* osl_getHomeDir returns file URL */ - osl_getHomeDir( osl_getCurrentSecurity(), &pTmp2 ); - - /* remove "file://" prefix */ - rtl_uString_newFromStr_WithLength( &pTmp2, pTmp2->buffer + 7, pTmp2->length - 7 ); - - /* replace '~' in original string */ - rtl_uString_newReplaceStrAt( &pTmp, pTmp, 0, 1, pTmp2 ); - rtl_uString_release( pTmp2 ); - } - - else + if (end - p >= 2 && p[0] == '/' && p[1] == '/') { + p += 2; + sal_Int32 i = rtl_ustr_indexOfChar_WithLength(p, end - p, '/'); + p1 = i < 0 ? end : p + i; + if (p1 != p && + (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( + p, p1 - p, RTL_CONSTASCII_STRINGPARAM("localhost")) != + 0) && + rtl_ustr_ascii_compare_WithLength(p, p1 - p, "127.0.0.1") != 0) { - /* FIXME: replace ~user with users home directory */ return osl_File_E_INVAL; } + p = p1; + if (p == end) { + *path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")); + return osl_File_E_None; + } } - - /* temporary check for top 5 wrong usage strings (which are valid but unlikly filenames) */ - /* - OSL_ASSERT( !findWrongUsage( pTmp->buffer, pTmp->length ) ); - */ - - *pustrSystemPath = pTmp; + if (homeAbbreviation && end - p >= 2 && p[0] == '/' && p[1] == '~') { + p += 2; + sal_Int32 i = rtl_ustr_indexOfChar_WithLength(p, end - p, '/'); + p1 = i < 0 ? end : p + i; + if (p1 == p) { + rtl::OUString home; + if (!osl::Security().getHomeDir(home)) { + return osl_File_E_INVAL; + } + oslFileError e = getSystemPathFromFileUrl(home, path, false); + if (e != osl_File_E_None) { + return e; + } + } else { + return osl_File_E_INVAL; //TODO + } + p = p1; + } + rtl::OUString d( + rtl::Uri::decode( + rtl::OUString(p, end - p), rtl_UriDecodeWithCharset, + RTL_TEXTENCODING_UTF8)); + if (d.indexOf(0) >=0) { + return osl_File_E_INVAL; + } + *path += d; return osl_File_E_None; } +} + +oslFileError osl_getSystemPathFromFileURL( + rtl_uString * pustrFileURL, rtl_uString ** ppustrSystemPath) +{ + rtl::OUString p; + oslFileError e = getSystemPathFromFileUrl( + rtl::OUString(pustrFileURL), &p, true); + if (e == osl_File_E_None) { + rtl_uString_assign(ppustrSystemPath, p.pData); + } + return e; +} /****************************************************************************/ /* osl_getFileURLFromSystemPath */ diff --git a/sal/osl/unx/makefile.mk b/sal/osl/unx/makefile.mk index 4a1c1130886b..92e701430194 100644 --- a/sal/osl/unx/makefile.mk +++ b/sal/osl/unx/makefile.mk @@ -41,6 +41,7 @@ PROJECTPCHSOURCE=cont_pch TARGETTYPE=CUI +ENABLE_EXCEPTIONS=TRUE # --- Settings ----------------------------------------------------- .INCLUDE : settings.mk diff --git a/sal/osl/w32/file_url.cxx b/sal/osl/w32/file_url.cxx index 75e9b98f0595..82fd8d2fbc74 100644 --- a/sal/osl/w32/file_url.cxx +++ b/sal/osl/w32/file_url.cxx @@ -601,6 +601,11 @@ static sal_Bool _osl_decodeURL( rtl_String* strUTF8, rtl_uString** pstrDecodedUR { switch ( *pSrc ) { + case 0: + case '?': + case '#': + bValidEncoded = false; + break; case '%': { sal_Char aToken[3]; |