diff options
-rw-r--r-- | sal/inc/uri_internal.hxx | 40 | ||||
-rw-r--r-- | sal/osl/unx/file_impl.hxx | 4 | ||||
-rw-r--r-- | sal/osl/unx/file_misc.cxx | 170 | ||||
-rw-r--r-- | sal/osl/unx/file_path_helper.cxx | 96 | ||||
-rw-r--r-- | sal/osl/unx/file_path_helper.hxx | 34 | ||||
-rw-r--r-- | sal/osl/unx/file_stat.cxx | 39 | ||||
-rw-r--r-- | sal/osl/unx/file_url.cxx | 234 | ||||
-rw-r--r-- | sal/osl/unx/file_url.hxx | 9 | ||||
-rw-r--r-- | sal/osl/unx/uunxapi.cxx | 74 | ||||
-rw-r--r-- | sal/osl/unx/uunxapi.hxx | 14 | ||||
-rw-r--r-- | sal/rtl/uri.cxx | 35 |
11 files changed, 509 insertions, 240 deletions
diff --git a/sal/inc/uri_internal.hxx b/sal/inc/uri_internal.hxx new file mode 100644 index 000000000000..0ec0650cab63 --- /dev/null +++ b/sal/inc/uri_internal.hxx @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SAL_INC_URI_INTERNAL_HXX +#define INCLUDED_SAL_INC_URI_INTERNAL_HXX + +#include <sal/config.h> + +namespace rtl::uri::detail +{ +enum EscapeType +{ + EscapeNo, + EscapeChar, + EscapeOctet +}; + +sal_uInt32 readUcs4(sal_Unicode const** pBegin, sal_Unicode const* pEnd, bool bEncoded, + rtl_TextEncoding eCharset, EscapeType* pType); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sal/osl/unx/file_impl.hxx b/sal/osl/unx/file_impl.hxx index de7a450e478d..eadb1257a068 100644 --- a/sal/osl/unx/file_impl.hxx +++ b/sal/osl/unx/file_impl.hxx @@ -28,11 +28,11 @@ struct DirectoryItem_Impl { sal_Int32 m_RefCount; - rtl_uString * const m_ustrFilePath; /* holds native file name */ + rtl_String * const m_strFilePath; /* holds native file name */ unsigned char const m_DType; explicit DirectoryItem_Impl( - rtl_uString * ustrFilePath, unsigned char DType = 0); + rtl_String * strFilePath, unsigned char DType = 0); ~DirectoryItem_Impl(); static void * operator new(size_t n); diff --git a/sal/osl/unx/file_misc.cxx b/sal/osl/unx/file_misc.cxx index 1690ca884dda..4e33e06da0ae 100644 --- a/sal/osl/unx/file_misc.cxx +++ b/sal/osl/unx/file_misc.cxx @@ -48,6 +48,8 @@ #include <algorithm> #include <cassert> +#include <cstring> +#include <memory> #include <new> #ifdef ANDROID @@ -66,7 +68,7 @@ namespace { struct DirectoryImpl { - OUString ustrPath; /* holds native directory path */ + OString strPath; /* holds native directory path */ DIR* pDirStruct; #ifdef ANDROID enum Kind @@ -82,18 +84,18 @@ struct DirectoryImpl } DirectoryItem_Impl::DirectoryItem_Impl( - rtl_uString * ustrFilePath, unsigned char DType) + rtl_String * strFilePath, unsigned char DType) : m_RefCount (1), - m_ustrFilePath (ustrFilePath), + m_strFilePath (strFilePath), m_DType (DType) { - if (m_ustrFilePath != nullptr) - rtl_uString_acquire(m_ustrFilePath); + if (m_strFilePath != nullptr) + rtl_string_acquire(m_strFilePath); } DirectoryItem_Impl::~DirectoryItem_Impl() { - if (m_ustrFilePath != nullptr) - rtl_uString_release(m_ustrFilePath); + if (m_strFilePath != nullptr) + rtl_string_release(m_strFilePath); } void * DirectoryItem_Impl::operator new(size_t n) @@ -146,92 +148,93 @@ static oslFileError osl_psz_removeDirectory(const sal_Char* pszPath); oslFileError SAL_CALL osl_openDirectory(rtl_uString* ustrDirectoryURL, oslDirectory* pDirectory) { - rtl_uString* ustrSystemPath = nullptr; oslFileError eRet; - char path[PATH_MAX]; + OString path; if ((ustrDirectoryURL == nullptr) || (ustrDirectoryURL->length == 0) || (pDirectory == nullptr)) return osl_File_E_INVAL; /* convert file URL to system path */ - eRet = osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL, &ustrSystemPath); + eRet = osl::detail::convertUrlToPathname(OUString::unacquired(&ustrDirectoryURL), &path); if( eRet != osl_File_E_None ) return eRet; - osl_systemPathRemoveSeparator(ustrSystemPath); + osl_systemPathRemoveSeparator(path.pData); - /* convert unicode path to text */ - if ( UnicodeToText( path, PATH_MAX, ustrSystemPath->buffer, ustrSystemPath->length ) #ifdef MACOSX - && macxp_resolveAlias( path, PATH_MAX ) == 0 -#endif /* MACOSX */ - ) { + auto const n = std::max(int(path.getLength() + 1), int(PATH_MAX)); + auto const tmp = std::make_unique<char[]>(n); + std::strcpy(tmp.get(), path.getStr()); + if (macxp_resolveAlias(tmp.get(), n) != 0) { + return oslTranslateFileError(errno); + } + path = OString(tmp.get(), std::strlen(tmp.get())); + } +#endif /* MACOSX */ + #ifdef ANDROID - if( strncmp( path, "/assets/", sizeof( "/assets/" ) - 1) == 0 ) + if( strncmp( path.getStr(), "/assets/", sizeof( "/assets/" ) - 1) == 0 ) + { + lo_apk_dir *pdir = lo_apk_opendir( path.getStr() ); + + if( pdir ) { - lo_apk_dir *pdir = lo_apk_opendir( path ); + DirectoryImpl* pDirImpl = new(std::nothrow) DirectoryImpl; - if( pdir ) + if( pDirImpl ) { - DirectoryImpl* pDirImpl = new(std::nothrow) DirectoryImpl; - - if( pDirImpl ) - { - pDirImpl->eKind = DirectoryImpl::KIND_ASSETS; - pDirImpl->pApkDirStruct = pdir; - pDirImpl->ustrPath = OUString(ustrSystemPath, SAL_NO_ACQUIRE); - - *pDirectory = (oslDirectory) pDirImpl; - return osl_File_E_None; - } - else - { - errno = ENOMEM; - lo_apk_closedir( pdir ); - } + pDirImpl->eKind = DirectoryImpl::KIND_ASSETS; + pDirImpl->pApkDirStruct = pdir; + pDirImpl->strPath = path; + + *pDirectory = (oslDirectory) pDirImpl; + return osl_File_E_None; + } + else + { + errno = ENOMEM; + lo_apk_closedir( pdir ); } } - else + } + else #endif - { - /* open directory */ - DIR *pdir = opendir( path ); + { + /* open directory */ + DIR *pdir = opendir( path.getStr() ); - if( pdir ) - { - SAL_INFO("sal.file", "opendir(" << path << ") => " << pdir); + if( pdir ) + { + SAL_INFO("sal.file", "opendir(" << path << ") => " << pdir); - /* create and initialize impl structure */ - DirectoryImpl* pDirImpl = new(std::nothrow) DirectoryImpl; + /* create and initialize impl structure */ + DirectoryImpl* pDirImpl = new(std::nothrow) DirectoryImpl; - if( pDirImpl ) - { - pDirImpl->pDirStruct = pdir; - pDirImpl->ustrPath = OUString(ustrSystemPath, SAL_NO_ACQUIRE); + if( pDirImpl ) + { + pDirImpl->pDirStruct = pdir; + pDirImpl->strPath = path; #ifdef ANDROID - pDirImpl->eKind = DirectoryImpl::KIND_DIRENT; + pDirImpl->eKind = DirectoryImpl::KIND_DIRENT; #endif - *pDirectory = static_cast<oslDirectory>(pDirImpl); - return osl_File_E_None; - } - errno = ENOMEM; - closedir( pdir ); - } - else - { - int e = errno; - SAL_INFO("sal.file", "opendir(" << path << "): " << UnixErrnoString(e)); - // Restore errno after possible modification by SAL_INFO above - errno = e; + *pDirectory = static_cast<oslDirectory>(pDirImpl); + return osl_File_E_None; } + errno = ENOMEM; + closedir( pdir ); + } + else + { + int e = errno; + SAL_INFO("sal.file", "opendir(" << path << "): " << UnixErrnoString(e)); + // Restore errno after possible modification by SAL_INFO above + errno = e; } } - rtl_uString_release( ustrSystemPath ); - return oslTranslateFileError(errno); } @@ -296,7 +299,7 @@ oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory pDirectory, SAL_WARN_IF(!pItem, "sal.file", "pItem is nullptr"); DirectoryImpl* pDirImpl = static_cast<DirectoryImpl*>(pDirectory); - OUString ustrFileName; + OString strFileName; struct dirent* pEntry; if ((pDirectory == nullptr) || (pItem == nullptr)) @@ -329,12 +332,9 @@ oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory pDirectory, filename = composed_name; #endif - /* convert file name to unicode */ - rtl_string2UString(&ustrFileName.pData, filename, strlen(filename), - osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS); - assert(ustrFileName.pData); + strFileName = OString(filename, strlen(filename)); - auto const ustrFilePath = osl::systemPathMakeAbsolutePath(pDirImpl->ustrPath, ustrFileName); + auto const strFilePath = osl::systemPathMakeAbsolutePath(pDirImpl->strPath, strFileName); DirectoryItem_Impl* pImpl = static_cast< DirectoryItem_Impl* >(*pItem); if (pImpl) @@ -343,9 +343,9 @@ oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory pDirectory, pImpl = nullptr; } #ifdef _DIRENT_HAVE_D_TYPE - pImpl = new DirectoryItem_Impl(ustrFilePath.pData, pEntry->d_type); + pImpl = new DirectoryItem_Impl(strFilePath.pData, pEntry->d_type); #else - pImpl = new DirectoryItem_Impl(ustrFilePath.pData); + pImpl = new DirectoryItem_Impl(strFilePath.pData); #endif /* _DIRENT_HAVE_D_TYPE */ *pItem = pImpl; @@ -354,27 +354,26 @@ oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory pDirectory, oslFileError SAL_CALL osl_getDirectoryItem(rtl_uString* ustrFileURL, oslDirectoryItem* pItem) { - rtl_uString* ustrSystemPath = nullptr; + OString strSystemPath; oslFileError osl_error = osl_File_E_INVAL; if ((!ustrFileURL) || (ustrFileURL->length == 0) || (!pItem)) return osl_File_E_INVAL; - osl_error = osl_getSystemPathFromFileURL_Ex(ustrFileURL, &ustrSystemPath); + osl_error = osl::detail::convertUrlToPathname(OUString::unacquired(&ustrFileURL), &strSystemPath); if (osl_error != osl_File_E_None) return osl_error; - osl_systemPathRemoveSeparator(ustrSystemPath); + osl_systemPathRemoveSeparator(strSystemPath.pData); - if (osl::access(OUString::unacquired(&ustrSystemPath), F_OK) == -1) + if (osl::access(strSystemPath, F_OK) == -1) { osl_error = oslTranslateFileError(errno); } else { - *pItem = new DirectoryItem_Impl(ustrSystemPath); + *pItem = new DirectoryItem_Impl(strSystemPath.pData); } - rtl_uString_release(ustrSystemPath); return osl_error; } @@ -493,9 +492,9 @@ static oslFileError osl_psz_removeDirectory( const sal_Char* pszPath ) return osl_File_E_None; } -static int path_make_parent(sal_Unicode* path) +static int path_make_parent(char* path) { - int i = rtl_ustr_lastIndexOfChar(path, '/'); + int i = rtl_str_lastIndexOfChar(path, '/'); if (i > 0) { @@ -506,7 +505,7 @@ static int path_make_parent(sal_Unicode* path) } static int create_dir_with_callback( - sal_Unicode* directory_path, + char* directory_path, oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc, void* pData) { @@ -515,7 +514,7 @@ static int create_dir_with_callback( if (aDirectoryCreationCallbackFunc) { OUString url; - osl::FileBase::getFileURLFromSystemPath(directory_path, url); + osl::detail::convertPathnameToUrl(directory_path, &url); aDirectoryCreationCallbackFunc(pData, url.pData); } return 0; @@ -524,11 +523,11 @@ static int create_dir_with_callback( } static oslFileError create_dir_recursively_( - sal_Unicode* dir_path, + char* dir_path, oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc, void* pData) { - OSL_PRECOND((rtl_ustr_getLength(dir_path) > 0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/'))), + OSL_PRECOND((rtl_str_getLength(dir_path) > 0) && ((dir_path + (rtl_str_getLength(dir_path) - 1)) != (dir_path + rtl_str_lastIndexOfChar(dir_path, '/'))), "Path must not end with a slash"); int native_err = create_dir_with_callback( @@ -565,8 +564,9 @@ oslFileError SAL_CALL osl_createDirectoryPath( if (aDirectoryUrl == nullptr) return osl_File_E_INVAL; - OUString sys_path; - oslFileError osl_error = osl_getSystemPathFromFileURL_Ex(aDirectoryUrl, &sys_path.pData); + OString sys_path; + oslFileError osl_error = osl::detail::convertUrlToPathname( + OUString::unacquired(&aDirectoryUrl), &sys_path); if (osl_error != osl_File_E_None) return osl_error; diff --git a/sal/osl/unx/file_path_helper.cxx b/sal/osl/unx/file_path_helper.cxx index e848586ccb3e..4d629f849868 100644 --- a/sal/osl/unx/file_path_helper.cxx +++ b/sal/osl/unx/file_path_helper.cxx @@ -32,27 +32,21 @@ const sal_Unicode FPH_CHAR_PATH_SEPARATOR = '/'; const sal_Unicode FPH_CHAR_DOT = '.'; const sal_Unicode FPH_CHAR_COLON = ':'; -static const OUStringLiteral FPH_PATH_SEPARATOR("/"); - -static const OUStringLiteral FPH_LOCAL_DIR_ENTRY("."); - -static const OUStringLiteral FPH_PARENT_DIR_ENTRY(".."); - -void osl_systemPathRemoveSeparator(rtl_uString* pustrPath) +void osl_systemPathRemoveSeparator(rtl_String* pstrPath) { - OSL_PRECOND(nullptr != pustrPath, "osl_systemPathRemoveSeparator: Invalid parameter"); - if (pustrPath != nullptr) + OSL_PRECOND(nullptr != pstrPath, "osl_systemPathRemoveSeparator: Invalid parameter"); + if (pstrPath != nullptr) { // maybe there are more than one separator at end // so we run in a loop - while ((pustrPath->length > 1) && (pustrPath->buffer[pustrPath->length - 1] == FPH_CHAR_PATH_SEPARATOR)) + while ((pstrPath->length > 1) && (pstrPath->buffer[pstrPath->length - 1] == FPH_CHAR_PATH_SEPARATOR)) { - pustrPath->length--; - pustrPath->buffer[pustrPath->length] = '\0'; + pstrPath->length--; + pstrPath->buffer[pstrPath->length] = '\0'; } - SAL_WARN_IF( !((0 == pustrPath->length) || (1 == pustrPath->length) || - (pustrPath->length > 1 && pustrPath->buffer[pustrPath->length - 1] != FPH_CHAR_PATH_SEPARATOR)), + SAL_WARN_IF( !((0 == pstrPath->length) || (1 == pstrPath->length) || + (pstrPath->length > 1 && pstrPath->buffer[pstrPath->length - 1] != FPH_CHAR_PATH_SEPARATOR)), "sal.osl", "osl_systemPathRemoveSeparator: Post condition failed"); } @@ -60,18 +54,18 @@ void osl_systemPathRemoveSeparator(rtl_uString* pustrPath) namespace { -void systemPathEnsureSeparator(OUString* ppustrPath) +template<typename T> void systemPathEnsureSeparator(T* ppstrPath) { - assert(nullptr != ppustrPath); - sal_Int32 lp = ppustrPath->getLength(); - sal_Int32 i = ppustrPath->lastIndexOf(FPH_CHAR_PATH_SEPARATOR); + assert(nullptr != ppstrPath); + sal_Int32 lp = ppstrPath->getLength(); + sal_Int32 i = ppstrPath->lastIndexOf(FPH_CHAR_PATH_SEPARATOR); if ((lp > 1 && i != (lp - 1)) || ((lp < 2) && i < 0)) { - *ppustrPath += FPH_PATH_SEPARATOR; + *ppstrPath += "/"; } - SAL_WARN_IF( !ppustrPath->endsWith(FPH_PATH_SEPARATOR), + SAL_WARN_IF( !ppstrPath->endsWith("/"), "sal.osl", "systemPathEnsureSeparator: Post condition failed"); } @@ -84,11 +78,13 @@ bool osl_systemPathIsRelativePath(const rtl_uString* pustrPath) return ((pustrPath == nullptr) || (pustrPath->length == 0) || (pustrPath->buffer[0] != FPH_CHAR_PATH_SEPARATOR)); } -OUString osl::systemPathMakeAbsolutePath( - const OUString& BasePath, - const OUString& RelPath) +namespace { + +template<typename T> T systemPathMakeAbsolutePath_( + const T& BasePath, + const T& RelPath) { - OUString base(BasePath); + T base(BasePath); if (!base.isEmpty()) systemPathEnsureSeparator(&base); @@ -96,18 +92,34 @@ OUString osl::systemPathMakeAbsolutePath( return base + RelPath; } +} + +OString osl::systemPathMakeAbsolutePath( + const OString& BasePath, + const OString& RelPath) +{ + return systemPathMakeAbsolutePath_(BasePath, RelPath); +} + +OUString osl::systemPathMakeAbsolutePath( + const OUString& BasePath, + const OUString& RelPath) +{ + return systemPathMakeAbsolutePath_(BasePath, RelPath); +} + void osl_systemPathGetFileNameOrLastDirectoryPart( - const rtl_uString* pustrPath, - rtl_uString** ppustrFileNameOrLastDirPart) + const rtl_String* pstrPath, + rtl_String** ppstrFileNameOrLastDirPart) { - OSL_PRECOND(pustrPath && ppustrFileNameOrLastDirPart, + OSL_PRECOND(pstrPath && ppstrFileNameOrLastDirPart, "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter"); - OUString path(const_cast<rtl_uString*>(pustrPath)); + OString path(const_cast<rtl_String*>(pstrPath)); osl_systemPathRemoveSeparator(path.pData); - OUString last_part; + OString last_part; if (path.getLength() > 1 || (path.getLength() == 1 && path[0] != FPH_CHAR_PATH_SEPARATOR)) { @@ -115,18 +127,18 @@ void osl_systemPathGetFileNameOrLastDirectoryPart( idx_ps++; // always right to increment by one even if idx_ps == -1! last_part = path.copy(idx_ps); } - rtl_uString_assign(ppustrFileNameOrLastDirPart, last_part.pData); + rtl_string_assign(ppstrFileNameOrLastDirPart, last_part.pData); } bool osl_systemPathIsHiddenFileOrDirectoryEntry( - const rtl_uString* pustrPath) + const rtl_String* pstrPath) { - OSL_PRECOND(nullptr != pustrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter"); - if ((pustrPath == nullptr) || (pustrPath->length == 0)) + OSL_PRECOND(nullptr != pstrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter"); + if ((pstrPath == nullptr) || (pstrPath->length == 0)) return false; - OUString fdp; - osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &fdp.pData); + OString fdp; + osl_systemPathGetFileNameOrLastDirectoryPart(pstrPath, &fdp.pData); return ((fdp.pData->length > 0) && (fdp.pData->buffer[0] == FPH_CHAR_DOT) && @@ -134,16 +146,16 @@ bool osl_systemPathIsHiddenFileOrDirectoryEntry( } bool osl_systemPathIsLocalOrParentDirectoryEntry( - const rtl_uString* pustrPath) + const rtl_String* pstrPath) { - OSL_PRECOND(pustrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter"); + OSL_PRECOND(pstrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter"); - OUString dirent; + OString dirent; - osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &dirent.pData); + osl_systemPathGetFileNameOrLastDirectoryPart(pstrPath, &dirent.pData); - return (dirent == FPH_LOCAL_DIR_ENTRY || - dirent == FPH_PARENT_DIR_ENTRY); + return (dirent == "." || + dirent == ".."); } /** Simple iterator for a path list separated by the specified character @@ -231,7 +243,7 @@ bool osl_searchPath( systemPathEnsureSeparator(&p); p += fp; - if (osl::access(p, F_OK) > -1) + if (osl::access(osl::OUStringToOString(p), F_OK) > -1) { bfound = true; rtl_uString_assign(ppustrPathFound, p.pData); diff --git a/sal/osl/unx/file_path_helper.hxx b/sal/osl/unx/file_path_helper.hxx index b969cfebf5ba..e210b27a3866 100644 --- a/sal/osl/unx/file_path_helper.hxx +++ b/sal/osl/unx/file_path_helper.hxx @@ -28,15 +28,15 @@ Removes the last separator from the given system path if any and if the path is not the root path '/' - @param ppustrPath[inout] a system path if the path is not the root path + @param ppstrPath[inout] a system path if the path is not the root path and the last character is a path separator it - will be cut off ppustrPath must not be NULL and - must point to a valid rtl_uString + will be cut off ppstrPath must not be NULL and + must point to a valid rtl_String @returns nothing */ -void osl_systemPathRemoveSeparator(rtl_uString* pustrPath); +void osl_systemPathRemoveSeparator(rtl_String* pstrPath); /** Returns true if the given path is a relative path and so starts not with '/' @@ -53,12 +53,12 @@ bool osl_systemPathIsRelativePath( /** Returns the file or the directory part of the given path - @param pustrPath [in] a system path, must not be NULL + @param pstrPath [in] a system path, must not be NULL - @param ppustrFileOrDirPart [out] on return receives the last part of the - given directory or the file name if pustrPath is the + @param ppstrFileOrDirPart [out] on return receives the last part of the + given directory or the file name if pstrPath is the root path '/' an empty string will be returned if - pustrPath has a trailing '/' the last part before the + pstrPath has a trailing '/' the last part before the '/' will be returned else the part after the last '/' will be returned @@ -66,8 +66,8 @@ bool osl_systemPathIsRelativePath( */ void osl_systemPathGetFileNameOrLastDirectoryPart( - const rtl_uString* pustrPath, - rtl_uString** ppustrFileNameOrLastDirPart); + const rtl_String* pstrPath, + rtl_String** ppstrFileNameOrLastDirPart); /** @param pustrPath [in] a system path, must not be NULL @@ -78,7 +78,7 @@ void osl_systemPathGetFileNameOrLastDirectoryPart( */ bool osl_systemPathIsHiddenFileOrDirectoryEntry( - const rtl_uString* pustrPath); + const rtl_String* pustrPath); /************************************************ osl_systemPathIsLocalOrParentDirectoryEntry @@ -86,7 +86,7 @@ bool osl_systemPathIsHiddenFileOrDirectoryEntry( system path is the local directory entry '.' or the parent directory entry '..' - @param pustrPath [in] a system path, + @param pstrPath [in] a system path, must not be NULL @returns sal_True if the last part of the @@ -96,7 +96,7 @@ bool osl_systemPathIsHiddenFileOrDirectoryEntry( ************************************************/ bool osl_systemPathIsLocalOrParentDirectoryEntry( - const rtl_uString* pustrPath); + const rtl_String* pstrPath); /************************************************ osl_searchPath @@ -146,7 +146,7 @@ namespace osl ******************************************/ - inline void systemPathRemoveSeparator(/*inout*/ OUString& Path) + inline void systemPathRemoveSeparator(/*inout*/ OString& Path) { osl_systemPathRemoveSeparator(Path.pData); } @@ -198,6 +198,10 @@ namespace osl *****************************************/ + OString systemPathMakeAbsolutePath( + const OString& BasePath, + const OString& RelPath); + OUString systemPathMakeAbsolutePath( const OUString& BasePath, const OUString& RelPath); @@ -220,7 +224,7 @@ namespace osl *********************************************/ inline bool systemPathIsHiddenFileOrDirectoryEntry( - const OUString& Path) + const OString& Path) { return osl_systemPathIsHiddenFileOrDirectoryEntry(Path.pData); } diff --git a/sal/osl/unx/file_stat.cxx b/sal/osl/unx/file_stat.cxx index 5f5c11eb54a8..dce25b5a1990 100644 --- a/sal/osl/unx/file_stat.cxx +++ b/sal/osl/unx/file_stat.cxx @@ -27,6 +27,7 @@ #include <unistd.h> #include <osl/diagnose.h> +#include <osl/thread.h> #include "file_impl.hxx" #include "file_error_transl.hxx" @@ -99,7 +100,7 @@ namespace required on network file systems not using unix semantics (AFS, see fdo#43095). */ - void set_file_access_rights(const OUString& file_path, oslFileStatus* pStat) + void set_file_access_rights(const OString& file_path, oslFileStatus* pStat) { pStat->uValidFields |= osl_FileStatus_Mask_Attributes; @@ -110,7 +111,7 @@ namespace pStat->uAttributes |= osl_File_Attribute_Executable; } - void set_file_hidden_status(const OUString& file_path, oslFileStatus* pStat) + void set_file_hidden_status(const OString& file_path, oslFileStatus* pStat) { pStat->uAttributes = osl::systemPathIsHiddenFileOrDirectoryEntry(file_path) ? osl_File_Attribute_Hidden : 0; pStat->uValidFields |= osl_FileStatus_Mask_Attributes; @@ -119,7 +120,7 @@ namespace /* the set_file_access_rights must be called after set_file_hidden_status(...) and set_file_access_mask(...) because of the hack in set_file_access_rights(...) */ void set_file_attributes( - const OUString& file_path, const struct stat& file_stat, const sal_uInt32 uFieldMask, oslFileStatus* pStat) + const OString& file_path, const struct stat& file_stat, const sal_uInt32 uFieldMask, oslFileStatus* pStat) { set_file_hidden_status(file_path, pStat); set_file_access_mask(file_stat, pStat); @@ -168,27 +169,29 @@ namespace (field_mask & osl_FileStatus_Mask_Validate)); } - oslFileError set_link_target_url(const OUString& file_path, oslFileStatus* pStat) + oslFileError set_link_target_url(const OString& file_path, oslFileStatus* pStat) { - OUString link_target; + OString link_target; if (!osl::realpath(file_path, link_target)) return oslTranslateFileError(errno); - oslFileError osl_error = osl_getFileURLFromSystemPath(link_target.pData, &pStat->ustrLinkTargetURL); + OUString url; + oslFileError osl_error = osl::detail::convertPathnameToUrl(link_target, &url); if (osl_error != osl_File_E_None) return osl_error; + rtl_uString_assign(&pStat->ustrLinkTargetURL, url.pData); pStat->uValidFields |= osl_FileStatus_Mask_LinkTargetURL; return osl_File_E_None; } oslFileError setup_osl_getFileStatus( - DirectoryItem_Impl * pImpl, oslFileStatus* pStat, OUString& file_path) + DirectoryItem_Impl * pImpl, oslFileStatus* pStat, OString& file_path) { if ((pImpl == nullptr) || (pStat == nullptr)) return osl_File_E_INVAL; - file_path = OUString(pImpl->m_ustrFilePath); + file_path = OString(pImpl->m_strFilePath); OSL_ASSERT(!file_path.isEmpty()); if (file_path.isEmpty()) return osl_File_E_INVAL; @@ -203,7 +206,7 @@ oslFileError SAL_CALL osl_getFileStatus(oslDirectoryItem Item, oslFileStatus* pS { DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(Item); - OUString file_path; + OString file_path; oslFileError osl_error = setup_osl_getFileStatus(pImpl, pStat, file_path); if (osl_error != osl_File_E_None) return osl_error; @@ -241,15 +244,23 @@ oslFileError SAL_CALL osl_getFileStatus(oslDirectoryItem Item, oslFileStatus* pS if (uFieldMask & osl_FileStatus_Mask_FileURL) { - if ((osl_error = osl_getFileURLFromSystemPath(file_path.pData, &pStat->ustrFileURL)) != osl_File_E_None) + OUString url; + if ((osl_error = osl::detail::convertPathnameToUrl(file_path, &url)) != osl_File_E_None) return osl_error; + rtl_uString_assign(&pStat->ustrFileURL, url.pData); pStat->uValidFields |= osl_FileStatus_Mask_FileURL; } if (uFieldMask & osl_FileStatus_Mask_FileName) { - osl_systemPathGetFileNameOrLastDirectoryPart(file_path.pData, &pStat->ustrFileName); + OString name; + osl_systemPathGetFileNameOrLastDirectoryPart(file_path.pData, &name.pData); + bool ok = rtl_convertStringToUString( + &pStat->ustrFileName, name.getStr(), name.getLength(), osl_getThreadTextEncoding(), + (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT + | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT)); + assert(ok); (void)ok; pStat->uValidFields |= osl_FileStatus_Mask_FileName; } return osl_File_E_None; @@ -427,13 +438,13 @@ SAL_CALL osl_identicalDirectoryItem( oslDirectoryItem a, oslDirectoryItem b) if (a == b) return true; /* same name => same item, unless renaming / moving madness has occurred */ - if (pA->m_ustrFilePath == pB->m_ustrFilePath) + if (pA->m_strFilePath == pB->m_strFilePath) return true; struct stat a_stat, b_stat; - if (osl::lstat(OUString(pA->m_ustrFilePath), a_stat) != 0 || - osl::lstat(OUString(pB->m_ustrFilePath), b_stat) != 0) + if (osl::lstat(OString(pA->m_strFilePath), a_stat) != 0 || + osl::lstat(OString(pB->m_strFilePath), b_stat) != 0) return false; return (a_stat.st_ino == b_stat.st_ino); diff --git a/sal/osl/unx/file_url.cxx b/sal/osl/unx/file_url.cxx index 043199ae9522..d149d31e1252 100644 --- a/sal/osl/unx/file_url.cxx +++ b/sal/osl/unx/file_url.cxx @@ -21,8 +21,12 @@ #include "system.hxx" +#include <algorithm> #include <cassert> +#include <cstring> #include <stdexcept> +#include <string_view> +#include <type_traits> #include <limits.h> #include <errno.h> #include <strings.h> @@ -36,13 +40,17 @@ #include <osl/process.h> #include <rtl/character.hxx> +#include <rtl/strbuf.hxx> #include <rtl/uri.h> #include <rtl/uri.hxx> #include <rtl/ustring.hxx> #include <rtl/ustrbuf.h> +#include <rtl/ustrbuf.hxx> #include <rtl/textcvt.h> #include <sal/log.hxx> +#include <uri_internal.hxx> + #include "file_error_transl.hxx" #include "file_path_helper.hxx" @@ -99,8 +107,106 @@ oslFileError SAL_CALL osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uStrin namespace { -oslFileError getSystemPathFromFileUrl( - OUString const & url, OUString * path, bool resolveHome) + class UnicodeToTextConverter_Impl + { + rtl_UnicodeToTextConverter const m_converter; + + UnicodeToTextConverter_Impl() + : m_converter (rtl_createUnicodeToTextConverter (osl_getThreadTextEncoding())) + {} + + ~UnicodeToTextConverter_Impl() + { + rtl_destroyUnicodeToTextConverter (m_converter); + } + public: + static UnicodeToTextConverter_Impl & getInstance() + { + static UnicodeToTextConverter_Impl g_theConverter; + return g_theConverter; + } + + sal_Size convert( + sal_Unicode const * pSrcBuf, sal_Size nSrcChars, sal_Char * pDstBuf, sal_Size nDstBytes, + sal_uInt32 nFlags, sal_uInt32 * pInfo, sal_Size * pSrcCvtChars) + { + OSL_ASSERT(m_converter != nullptr); + return rtl_convertUnicodeToText ( + m_converter, nullptr, pSrcBuf, nSrcChars, pDstBuf, nDstBytes, nFlags, pInfo, pSrcCvtChars); + } + }; + +bool convert(OUStringBuffer const & in, OStringBuffer * append) { + assert(append != nullptr); + for (sal_Size convert = in.getLength();;) { + auto const oldLen = append->getLength(); + auto n = std::min( + std::max(convert, sal_Size(PATH_MAX)), + sal_Size(std::numeric_limits<sal_Int32>::max() - oldLen)); + // approximation of required converted size + auto s = append->appendUninitialized(n); + sal_uInt32 info; + sal_Size converted; + //TODO: context, for reliable treatment of DESTBUFFERTOSMALL: + n = UnicodeToTextConverter_Impl::getInstance().convert( + in.getStr() + in.getLength() - convert, convert, s, n, + (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR + | RTL_UNICODETOTEXT_FLAGS_FLUSH), + &info, &converted); + if ((info & RTL_UNICODETOTEXT_INFO_ERROR) != 0) { + return false; + } + append->setLength(oldLen + n); + assert(converted <= convert); + convert -= converted; + assert((convert == 0) == ((info & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL) == 0)); + if ((info & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL) == 0) { + break; + } + } + return true; +} + +bool decodeFromUtf8(std::u16string_view text, OString * result) { + assert(result != nullptr); + auto p = text.data(); + auto const end = p + text.size(); + OUStringBuffer ubuf; + OStringBuffer bbuf; + while (p < end) { + rtl::uri::detail::EscapeType t; + sal_uInt32 c = rtl::uri::detail::readUcs4(&p, end, true, RTL_TEXTENCODING_UTF8, &t); + switch (t) { + case rtl::uri::detail::EscapeNo: + if (c == '%') { + return false; + } + [[fallthrough]]; + case rtl::uri::detail::EscapeChar: + if (rtl::isSurrogate(c)) { + return false; + } + ubuf.appendUtf32(c); + break; + case rtl::uri::detail::EscapeOctet: + if (!convert(ubuf, &bbuf)) { + return false; + } + ubuf.setLength(0); + assert(c <= 0xFF); + bbuf.append(char(c)); + break; + } + } + if (!convert(ubuf, &bbuf)) { + return false; + } + *result = bbuf.makeStringAndClear(); + return true; +} + +template<typename T> oslFileError getSystemPathFromFileUrl( + OUString const & url, T * path, bool resolveHome) { assert(path != nullptr); // For compatibility with assumptions in other parts of the code base, @@ -178,8 +284,16 @@ oslFileError getSystemPathFromFileUrl( if (url.indexOf("%2F", i) != -1 || url.indexOf("%2f", i) != -1) return osl_File_E_INVAL; - *path = rtl::Uri::decode( - url.copy(i), rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8); + if constexpr (std::is_same_v<T, rtl::OString>) { + if (!decodeFromUtf8(std::u16string_view(url).substr(i), path)) { + return osl_File_E_INVAL; + } + } else if constexpr (std::is_same_v<T, rtl::OUString>) { + *path = rtl::Uri::decode( + url.copy(i), rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8); + } else { + static_assert(std::is_same_v<T, rtl::OString> || std::is_same_v<T, rtl::OUString>); + } // Path must not contain %2F: if (path->indexOf('\0') != -1) return osl_File_E_INVAL; @@ -711,55 +825,23 @@ oslFileError osl_searchFileURL(rtl_uString* ustrFilePath, rtl_uString* ustrSearc oslFileError FileURLToPath(char * buffer, size_t bufLen, rtl_uString* ustrFileURL) { - rtl_uString* ustrSystemPath = nullptr; - oslFileError osl_error = osl_getSystemPathFromFileURL(ustrFileURL, &ustrSystemPath); + OString strSystemPath; + oslFileError osl_error = osl::detail::convertUrlToPathname( + OUString::unacquired(&ustrFileURL), &strSystemPath); if(osl_error != osl_File_E_None) return osl_error; - osl_systemPathRemoveSeparator(ustrSystemPath); - - /* convert unicode path to text */ - if(!UnicodeToText( buffer, bufLen, ustrSystemPath->buffer, ustrSystemPath->length)) - osl_error = oslTranslateFileError(errno); + osl_systemPathRemoveSeparator(strSystemPath.pData); - rtl_uString_release(ustrSystemPath); + if (sal_uInt32(strSystemPath.getLength()) >= bufLen) { + return osl_File_E_OVERFLOW; + } + std::strcpy(buffer, strSystemPath.getStr()); return osl_error; } -namespace -{ - class UnicodeToTextConverter_Impl - { - rtl_UnicodeToTextConverter const m_converter; - - UnicodeToTextConverter_Impl() - : m_converter (rtl_createUnicodeToTextConverter (osl_getThreadTextEncoding())) - {} - - ~UnicodeToTextConverter_Impl() - { - rtl_destroyUnicodeToTextConverter (m_converter); - } - public: - static UnicodeToTextConverter_Impl & getInstance() - { - static UnicodeToTextConverter_Impl g_theConverter; - return g_theConverter; - } - - sal_Size convert( - sal_Unicode const * pSrcBuf, sal_Size nSrcChars, sal_Char * pDstBuf, sal_Size nDstBytes, - sal_uInt32 nFlags, sal_uInt32 * pInfo, sal_Size * pSrcCvtChars) - { - OSL_ASSERT(m_converter != nullptr); - return rtl_convertUnicodeToText ( - m_converter, nullptr, pSrcBuf, nSrcChars, pDstBuf, nDstBytes, nFlags, pInfo, pSrcCvtChars); - } - }; -} - int UnicodeToText( char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen ) { sal_uInt32 nInfo = 0; @@ -837,4 +919,68 @@ int TextToUnicode( return nDestBytes; } +oslFileError osl::detail::convertUrlToPathname(OUString const & url, OString * pathname) { + assert(pathname != nullptr); + oslFileError e; + try { + e = getSystemPathFromFileUrl(url, pathname, true); + } catch (std::length_error &) { + e = osl_File_E_RANGE; + } + if (e == osl_File_E_None && !pathname->startsWith("/")) { + e = osl_File_E_INVAL; + } + return e; +} + +oslFileError osl::detail::convertPathnameToUrl(OString const & pathname, OUString * url) { + assert(url != nullptr); + OUStringBuffer buf("file:"); + if (pathname.startsWith("/")) { + buf.append("//"); + // so if pathname should ever start with "//" that isn't mistaken for an authority + // component + } + for (sal_Size convert = pathname.getLength();;) { + OUStringBuffer ubuf; + auto n = std::max(convert, sal_Size(PATH_MAX)); // approximation of required converted size + auto s = ubuf.appendUninitialized(n); + sal_uInt32 info; + sal_Size converted; + //TODO: context, for reliable treatment of DESTBUFFERTOSMALL: + n = TextToUnicodeConverter_Impl::getInstance().convert( + pathname.getStr() + pathname.getLength() - convert, convert, s, n, + (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR + | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR | RTL_TEXTTOUNICODE_FLAGS_FLUSH), + &info, &converted); + ubuf.setLength(n); + buf.append( + rtl::Uri::encode( + ubuf.makeStringAndClear(), uriCharClass, rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8)); + assert(converted <= convert); + convert -= converted; + if ((info & RTL_TEXTTOUNICODE_INFO_ERROR) != 0) { + assert(convert > 0); + //TODO: see writeEscapeOctet in sal/rtl/uri.cxx + buf.append("%"); + unsigned char c = pathname[pathname.getLength() - convert]; + assert(c >= 0x80); + static sal_Unicode const aHex[16] + = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }; /* '0'--'9', 'A'--'F' */ + buf.append(aHex[c >> 4]); + buf.append(aHex[c & 15]); + --convert; + continue; + } + assert((convert == 0) == ((info & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL) == 0)); + if ((info & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL) == 0) { + break; + } + } + *url = buf.makeStringAndClear(); + return osl_File_E_None; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/osl/unx/file_url.hxx b/sal/osl/unx/file_url.hxx index 7185ada4feb3..4b45d7f52aad 100644 --- a/sal/osl/unx/file_url.hxx +++ b/sal/osl/unx/file_url.hxx @@ -22,7 +22,10 @@ #include <osl/file.h> -namespace rtl { class OUString; } +namespace rtl { + class OString; + class OUString; +} oslFileError osl_getSystemPathFromFileURL_Ex(rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath); @@ -34,6 +37,10 @@ int TextToUnicode(const char* text, size_t text_buffer_size, sal_Unicode* unic_t namespace osl { namespace detail { +oslFileError convertUrlToPathname(rtl::OUString const & url, rtl::OString * pathname); + +oslFileError convertPathnameToUrl(rtl::OString const & pathname, rtl::OUString * url); + bool find_in_PATH(const rtl::OUString& file_path, rtl::OUString& result); } } diff --git a/sal/osl/unx/uunxapi.cxx b/sal/osl/unx/uunxapi.cxx index 45de25280980..1005140a2c91 100644 --- a/sal/osl/unx/uunxapi.cxx +++ b/sal/osl/unx/uunxapi.cxx @@ -31,7 +31,7 @@ #include <osl/detail/android-bootstrap.h> #endif -static OString OUStringToOString(const OUString& s) +OString osl::OUStringToOString(const OUString& s) { return OUStringToOString(s, osl_getThreadTextEncoding()); } @@ -156,9 +156,9 @@ static OString macxp_resolveAliasAndConvert(OString const & p) } #endif /* MACOSX */ -int osl::access(const OUString& pustrPath, int mode) +int osl::access(const OString& pstrPath, int mode) { - OString fn = OUStringToOString(pustrPath); + OString fn = pstrPath; #ifdef ANDROID if (fn == "/assets" || fn.startsWith("/assets/")) { @@ -194,16 +194,29 @@ int osl::access(const OUString& pustrPath, int mode) return result; } -bool osl::realpath(const OUString& pustrFileName, OUString& ppustrResolvedName) +namespace { + +OString toOString(OString const & s) { return s; } + +OString toOString(OUString const & s) { return osl::OUStringToOString(s); } + +template<typename T> T fromOString(OString const &) = delete; + +template<> OString fromOString(OString const & s) { return s; } + +template<> OUString fromOString(OString const & s) +{ return OStringToOUString(s, osl_getThreadTextEncoding()); } + +template<typename T> bool realpath_(const T& pstrFileName, T& ppstrResolvedName) { - OString fn = OUStringToOString(pustrFileName); + OString fn = toOString(pstrFileName); #ifdef ANDROID if (fn == "/assets" || fn.startsWith("/assets/")) { - if (osl::access(pustrFileName, F_OK) == -1) + if (osl::access(fn, F_OK) == -1) return false; - ppustrResolvedName = pustrFileName; + ppstrResolvedName = pstrFileName; return true; } @@ -216,7 +229,7 @@ bool osl::realpath(const OUString& pustrFileName, OUString& ppustrResolvedName) accessFilePathState *state = prepare_to_access_file_path(fn.getStr()); char rp[PATH_MAX]; - bool bRet = ::realpath(fn.getStr(), rp); + bool bRet = realpath(fn.getStr(), rp); int saved_errno = errno; if (!bRet) SAL_INFO("sal.file", "realpath(" << fn.getStr() << "): " << UnixErrnoString(saved_errno)); @@ -227,8 +240,7 @@ bool osl::realpath(const OUString& pustrFileName, OUString& ppustrResolvedName) if (bRet) { - ppustrResolvedName = OStringToOUString(OString(static_cast<sal_Char*>(rp)), - osl_getThreadTextEncoding()); + ppstrResolvedName = fromOString<T>(OString(static_cast<sal_Char*>(rp))); } errno = saved_errno; @@ -236,6 +248,18 @@ bool osl::realpath(const OUString& pustrFileName, OUString& ppustrResolvedName) return bRet; } +} + +bool osl::realpath(const OUString& pustrFileName, OUString& ppustrResolvedName) +{ + return realpath_(pustrFileName, ppustrResolvedName); +} + +bool osl::realpath(const OString& pstrFileName, OString& ppstrResolvedName) +{ + return realpath_(pstrFileName, ppstrResolvedName); +} + int stat_c(const char* cpPath, struct stat* buf) { #ifdef ANDROID @@ -286,9 +310,11 @@ int lstat_c(const char* cpPath, struct stat* buf) return result; } -int osl::lstat(const OUString& pustrPath, struct stat& buf) +namespace { + +template<typename T> int lstat_(const T& pstrPath, struct stat& buf) { - OString fn = OUStringToOString(pustrPath); + OString fn = toOString(pstrPath); #ifdef MACOSX fn = macxp_resolveAliasAndConvert(fn); @@ -297,20 +323,30 @@ int osl::lstat(const OUString& pustrPath, struct stat& buf) return lstat_c(fn.getStr(), &buf); } -int osl::mkdir(const OUString& path, mode_t mode) +} + +int osl::lstat(const OUString& pustrPath, struct stat& buf) +{ + return lstat_(pustrPath, buf); +} + +int osl::lstat(const OString& pstrPath, struct stat& buf) { - OString fn = OUStringToOString(path); + return lstat_(pstrPath, buf); +} - accessFilePathState *state = prepare_to_access_file_path(fn.getStr()); +int osl::mkdir(const OString& path, mode_t mode) +{ + accessFilePathState *state = prepare_to_access_file_path(path.getStr()); - int result = ::mkdir(OUStringToOString(path).getStr(), mode); + int result = ::mkdir(path.getStr(), mode); int saved_errno = errno; if (result == -1) - SAL_INFO("sal.file", "mkdir(" << OUStringToOString(path).getStr() << ",0" << std::oct << mode << std::dec << "): " << UnixErrnoString(saved_errno)); + SAL_INFO("sal.file", "mkdir(" << path << ",0" << std::oct << mode << std::dec << "): " << UnixErrnoString(saved_errno)); else - SAL_INFO("sal.file", "mkdir(" << OUStringToOString(path).getStr() << ",0" << std::oct << mode << std::dec << "): OK"); + SAL_INFO("sal.file", "mkdir(" << path << ",0" << std::oct << mode << std::dec << "): OK"); - done_accessing_file_path(fn.getStr(), state); + done_accessing_file_path(path.getStr(), state); errno = saved_errno; diff --git a/sal/osl/unx/uunxapi.hxx b/sal/osl/unx/uunxapi.hxx index 1d0b26c92dc2..f182b755e53b 100644 --- a/sal/osl/unx/uunxapi.hxx +++ b/sal/osl/unx/uunxapi.hxx @@ -32,6 +32,8 @@ int stat_c(const char *cpPath, struct stat* buf); int lstat_c(const char *cpPath, struct stat* buf); +int mkdir_c(OString const & path, mode_t mode); + int open_c(const char *cpPath, int oflag, int mode); int utime_c(const char *cpPath, struct utimbuf *times); @@ -40,7 +42,9 @@ int ftruncate_with_name(int fd, sal_uInt64 uSize, rtl_String* path); namespace osl { - int access(const OUString& ustrPath, int mode); + OString OUStringToOString(const OUString& s); + + int access(const OString& strPath, int mode); /*********************************** osl::realpath @@ -59,9 +63,15 @@ namespace osl const OUString& ustrFileName, OUString& ustrResolvedName); + bool realpath( + const OString& strFileName, + OString& strResolvedName); + int lstat(const OUString& ustrPath, struct stat& buf); - int mkdir(const OUString& aPath, mode_t aMode); + int lstat(const OString& strPath, struct stat& buf); + + int mkdir(const OString& aPath, mode_t aMode); } // end namespace osl #endif // INCLUDED_SAL_OSL_UNX_UUNXAPI_HXX diff --git a/sal/rtl/uri.cxx b/sal/rtl/uri.cxx index 07634c628de6..0504650b80fe 100644 --- a/sal/rtl/uri.cxx +++ b/sal/rtl/uri.cxx @@ -29,6 +29,8 @@ #include <sal/types.h> #include <sal/macros.h> +#include <uri_internal.hxx> + #include <algorithm> #include <cstddef> @@ -60,12 +62,9 @@ void writeUnicode(rtl_uString ** pBuffer, sal_Int32 * pCapacity, rtl_uStringbuffer_insert(pBuffer, pCapacity, (*pBuffer)->length, &cChar, 1); } -enum EscapeType -{ - EscapeNo, - EscapeChar, - EscapeOctet -}; +} + +namespace rtl::uri::detail { /** Read any of the following: @@ -214,6 +213,10 @@ sal_uInt32 readUcs4(sal_Unicode const ** pBegin, sal_Unicode const * pEnd, rtl::combineSurrogates(nChar, *(*pBegin)++) : nChar; } +} + +namespace { + void writeUcs4(rtl_uString ** pBuffer, sal_Int32 * pCapacity, sal_uInt32 nUtf32) { assert(rtl::isUnicodeCodePoint(nUtf32)); @@ -640,8 +643,8 @@ void SAL_CALL rtl_uriEncode(rtl_uString * pText, sal_Bool const * pCharClass, while (p < pEnd) { - EscapeType eType; - sal_uInt32 nUtf32 = readUcs4( + rtl::uri::detail::EscapeType eType; + sal_uInt32 nUtf32 = rtl::uri::detail::readUcs4( &p, pEnd, (eMechanism == rtl_UriEncodeKeepEscapes || eMechanism == rtl_UriEncodeCheckEscapes @@ -650,7 +653,7 @@ void SAL_CALL rtl_uriEncode(rtl_uString * pText, sal_Bool const * pCharClass, switch (eType) { - case EscapeNo: + case rtl::uri::detail::EscapeNo: if (isValid(pCharClass, nUtf32)) // implies nUtf32 <= 0x7F { writeUnicode(pResult, &nCapacity, @@ -666,7 +669,7 @@ void SAL_CALL rtl_uriEncode(rtl_uString * pText, sal_Bool const * pCharClass, } break; - case EscapeChar: + case rtl::uri::detail::EscapeChar: if (eMechanism == rtl_UriEncodeCheckEscapes && isValid(pCharClass, nUtf32)) // implies nUtf32 <= 0x7F { @@ -683,7 +686,7 @@ void SAL_CALL rtl_uriEncode(rtl_uString * pText, sal_Bool const * pCharClass, } break; - case EscapeOctet: + case rtl::uri::detail::EscapeOctet: writeEscapeOctet(pResult, &nCapacity, nUtf32); break; } @@ -714,11 +717,11 @@ void SAL_CALL rtl_uriDecode(rtl_uString * pText, while (p < pEnd) { - EscapeType eType; - sal_uInt32 nUtf32 = readUcs4(&p, pEnd, true, eCharset, &eType); + rtl::uri::detail::EscapeType eType; + sal_uInt32 nUtf32 = rtl::uri::detail::readUcs4(&p, pEnd, true, eCharset, &eType); switch (eType) { - case EscapeChar: + case rtl::uri::detail::EscapeChar: if (nUtf32 <= 0x7F && eMechanism == rtl_UriDecodeToIuri) { writeEscapeOctet(pResult, &nCapacity, nUtf32); @@ -726,11 +729,11 @@ void SAL_CALL rtl_uriDecode(rtl_uString * pText, } [[fallthrough]]; - case EscapeNo: + case rtl::uri::detail::EscapeNo: writeUcs4(pResult, &nCapacity, nUtf32); break; - case EscapeOctet: + case rtl::uri::detail::EscapeOctet: if (eMechanism == rtl_UriDecodeStrict) { rtl_uString_new(pResult); |