Kaydet (Commit) 1e8728c4 authored tarafından Michael Meeks's avatar Michael Meeks

Revert "#i116915# rewrote unx osl_getSystemPathFromFileURL to avoid mem leaks"

This reverts commit 8c015fbb.

Conflicts:
	sal/osl/unx/file_url.cxx
	sal/osl/unx/makefile.mk
	sal/prj/build.lst
	sal/qa/osl/getsystempathfromfileurl/test-getsystempathfromfileurl.cxx
üst 8004db55
......@@ -37,12 +37,12 @@
#include <unistd.h>
#include "osl/file.hxx"
#include <osl/security.hxx>
#include <osl/security.h>
#include <osl/diagnose.h>
#include <osl/thread.h>
#include <osl/process.h>
#include <rtl/uri.hxx>
#include <rtl/uri.h>
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.h>
#include "rtl/textcvt.h"
......@@ -146,99 +146,154 @@ oslFileError SAL_CALL osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uStrin
/* osl_getSystemPathFromFileURL */
/****************************************************************************/
namespace {
oslFileError getSystemPathFromFileUrl(
rtl::OUString const & url, rtl::OUString * path, bool homeAbbreviation)
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] = { ':', '/', '/' };
OSL_ASSERT(path != 0 && path->isEmpty());
sal_Unicode const * p = url.getStr();
sal_Unicode const * end = p + url.getLength();
/* 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 ((p == end) || (*p == UNICHAR_SLASH))
if( ( 0 == ustrFileURL->length ) || ( (sal_Unicode) '/' == ustrFileURL->buffer[0] ) )
{
return osl_File_E_INVAL;
}
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')))
/* 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;
if( -1 != rtl_ustr_indexOfStr_WithLength( ustrFileURL->buffer, ustrFileURL->length, encodedSlash, 3 ) )
{
rtl_uString * ustrPathToken = NULL;
sal_Int32 nOffset = 7;
do
{
return osl_File_E_INVAL;
}
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;
}
sal_Unicode const * p1 = p;
while (p1 != end && *p1 != ':' && *p1 != '/') {
++p1;
/* 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 );
}
if (p1 != end && *p1 == ':') {
if (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
p, p1 - p, RTL_CONSTASCII_STRINGPARAM("file")) !=
0)
/* 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 ) ) )
{
return osl_File_E_INVAL;
/* don't exclude the '/' */
nIndex += 9;
}
p = p1 + 1;
rtl_uString_release( pServer );
}
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)
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] ) )
{
return osl_File_E_INVAL;
}
p = p1;
if (p == end) {
*path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
return osl_File_E_None;
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 );
}
}
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
else
{
/* FIXME: replace ~user with users home directory */
return osl_File_E_INVAL;
}
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;
/* temporary check for top 5 wrong usage strings (which are valid but unlikly filenames) */
/*
OSL_ASSERT( !findWrongUsage( pTmp->buffer, pTmp->length ) );
*/
*pustrSystemPath = pTmp;
return osl_File_E_None;
}
/****************************************************************************/
......
......@@ -601,11 +601,6 @@ 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];
......
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#include <sal/types.h>
#include "cppunit/TestAssert.h"
#include "cppunit/TestFixture.h"
#include "cppunit/extensions/HelperMacros.h"
#include "cppunit/plugin/TestPlugIn.h"
#include "osl/file.hxx"
#if defined WNT
#define MY_PATH_IN "/c:/foo/bar"
#define MY_PATH_OUT "c:\\foo\\bar"
#define MY_PATH_OUT_CONT MY_PATH_OUT "\\"
#define MY_PATH_OUT_REL "foo\\bar"
#else
#define MY_PATH_IN "/foo/bar"
#define MY_PATH_OUT MY_PATH_IN
#define MY_PATH_OUT_CONT MY_PATH_OUT "/"
#define MY_PATH_OUT_REL "foo/bar"
#endif
namespace {
class Test: public CppUnit::TestFixture {
private:
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testBadScheme);
CPPUNIT_TEST(testNoScheme);
CPPUNIT_TEST(testBadAuthority);
CPPUNIT_TEST(testLocalhost1Authority);
CPPUNIT_TEST(testLocalhost2Authority);
CPPUNIT_TEST(testLocalhost3Authority);
CPPUNIT_TEST(testNoAuthority);
CPPUNIT_TEST(testEmptyPath);
CPPUNIT_TEST(testHomeAbbreviation);
CPPUNIT_TEST(testOtherHomeAbbreviation);
CPPUNIT_TEST(testRelative);
CPPUNIT_TEST(testEscape);
CPPUNIT_TEST(testBadEscape2f);
CPPUNIT_TEST(testBadEscape2F);
CPPUNIT_TEST(testBad0);
CPPUNIT_TEST(testBadEscape0);
CPPUNIT_TEST(testBadQuery);
CPPUNIT_TEST(testBadFragment);
CPPUNIT_TEST_SUITE_END();
void testBadScheme();
void testNoScheme();
void testBadAuthority();
void testLocalhost1Authority();
void testLocalhost2Authority();
void testLocalhost3Authority();
void testNoAuthority();
void testEmptyPath();
void testHomeAbbreviation();
void testOtherHomeAbbreviation();
void testRelative();
void testEscape();
void testBadEscape2f();
void testBadEscape2F();
void testBad0();
void testBadEscape0();
void testBadQuery();
void testBadFragment();
};
void Test::testBadScheme() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo:bar")), p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_INVAL, e);
CPPUNIT_ASSERT_EQUAL(rtl::OUString(), p);
}
void Test::testNoScheme() {
#if !defined WNT //TODO
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("//" MY_PATH_IN)), p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
CPPUNIT_ASSERT_EQUAL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(MY_PATH_OUT)), p);
#endif
}
void Test::testBadAuthority() {
#if defined UNX
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file://baz" MY_PATH_IN)), p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_INVAL, e);
CPPUNIT_ASSERT_EQUAL(rtl::OUString(), p);
#endif
}
void Test::testLocalhost1Authority() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("file://localhost" MY_PATH_IN)),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
CPPUNIT_ASSERT_EQUAL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(MY_PATH_OUT)), p);
}
void Test::testLocalhost2Authority() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("file://LOCALHOST" MY_PATH_IN)),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
CPPUNIT_ASSERT_EQUAL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(MY_PATH_OUT)), p);
}
void Test::testLocalhost3Authority() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("file://127.0.0.1" MY_PATH_IN)),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
CPPUNIT_ASSERT_EQUAL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(MY_PATH_OUT)), p);
}
void Test::testNoAuthority() {
#if !defined WNT //TODO
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(MY_PATH_IN)), p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
CPPUNIT_ASSERT_EQUAL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(MY_PATH_OUT)), p);
#endif
}
void Test::testEmptyPath() {
#if defined UNX
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file://")), p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
CPPUNIT_ASSERT_EQUAL(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")), p);
#endif
}
void Test::testHomeAbbreviation() {
#if defined UNX
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///~" MY_PATH_IN)), p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
// could theoretically fail due to osl::Security::getHomeDir problem
CPPUNIT_ASSERT(p.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(MY_PATH_OUT)));
#endif
}
void Test::testOtherHomeAbbreviation() {
#if defined UNX
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///~baz" MY_PATH_IN)),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_INVAL, e); // not supported for now
CPPUNIT_ASSERT_EQUAL(rtl::OUString(), p);
#endif
}
void Test::testRelative() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo/bar")), p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
CPPUNIT_ASSERT(
p.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(MY_PATH_OUT_REL)));
}
void Test::testEscape() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("file://" MY_PATH_IN "/b%61z")),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
CPPUNIT_ASSERT_EQUAL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(MY_PATH_OUT_CONT "baz")), p);
}
void Test::testBadEscape2f() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("file://" MY_PATH_IN "/b%2fz")),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_INVAL, e);
CPPUNIT_ASSERT_EQUAL(rtl::OUString(), p);
}
void Test::testBadEscape2F() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("file://" MY_PATH_IN "/b%2Fz")),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_INVAL, e);
CPPUNIT_ASSERT_EQUAL(rtl::OUString(), p);
}
void Test::testBad0() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("file://" MY_PATH_IN "/b\x00z")),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_INVAL, e);
CPPUNIT_ASSERT_EQUAL(rtl::OUString(), p);
}
void Test::testBadEscape0() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("file://" MY_PATH_IN "/b%00z")),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_INVAL, e);
CPPUNIT_ASSERT_EQUAL(rtl::OUString(), p);
}
void Test::testBadQuery() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file://" MY_PATH_IN "?baz")),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_INVAL, e);
CPPUNIT_ASSERT_EQUAL(rtl::OUString(), p);
}
void Test::testBadFragment() {
rtl::OUString p;
osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file://" MY_PATH_IN "#baz")),
p);
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_INVAL, e);
CPPUNIT_ASSERT_EQUAL(rtl::OUString(), p);
}
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
}
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment