summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2019-09-10 10:52:57 +0200
committerStephan Bergmann <sbergman@redhat.com>2019-09-17 15:05:11 +0200
commitcaa211b62048ac5037b3fd4320f3eb4dea7b639d (patch)
treecf1768b435ed71363e34b56682435628545a7293 /sal
parentb9ce783a4b8ea967281ed583842ee3d931d78ac7 (diff)
Better handling of non--UTF-8 filesystem pathnames in sal/osl/unx/
The idea is to internally in sal/osl/unx/ use OString instead of OUString to represent pathnames, so that the OString carries the actual bytes that make up the pathname. At the boundary of translating between pathname OStrings and file URL OUStrings, translate sequences of bytes that are valid according to osl_getThreadTextEncoding() into UTF-8 and translate other bytes into individual (percent-encoded) bytes in the file URL. This change required duplicating some of the internal functionality in sal/osl/unx/ for both OString and OUString, and to make part of sal/rtl/uri.cxx accessible from sal/osl/unx/ via new sal/inc/uri_internal.hxx. Change-Id: Id1ebaebe9e7f2d21f350f6b1a07849edee54331f Reviewed-on: https://gerrit.libreoffice.org/78798 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'sal')
-rw-r--r--sal/inc/uri_internal.hxx40
-rw-r--r--sal/osl/unx/file_impl.hxx4
-rw-r--r--sal/osl/unx/file_misc.cxx170
-rw-r--r--sal/osl/unx/file_path_helper.cxx96
-rw-r--r--sal/osl/unx/file_path_helper.hxx34
-rw-r--r--sal/osl/unx/file_stat.cxx39
-rw-r--r--sal/osl/unx/file_url.cxx234
-rw-r--r--sal/osl/unx/file_url.hxx9
-rw-r--r--sal/osl/unx/uunxapi.cxx74
-rw-r--r--sal/osl/unx/uunxapi.hxx14
-rw-r--r--sal/rtl/uri.cxx35
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);