summaryrefslogtreecommitdiff
path: root/sal/osl
diff options
context:
space:
mode:
authorsb <sb@openoffice.org>2011-05-12 17:53:15 +0100
committerCaolán McNamara <caolanm@redhat.com>2011-05-20 10:32:03 +0100
commit8c015fbb85f00fe1cc82e00ea1771ad9fba821d2 (patch)
treef55f4486cd76ccecd8bc78ee27d4e15fa089ed96 /sal/osl
parentf85638485cdc1ddd25f322ea4c30a386351f4bd5 (diff)
#i116915# rewrote unx osl_getSystemPathFromFileURL to avoid mem leaks
Diffstat (limited to 'sal/osl')
-rw-r--r--sal/osl/unx/file_url.cxx211
-rw-r--r--sal/osl/unx/makefile.mk1
-rw-r--r--sal/osl/w32/file_url.cxx5
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];