From caa211b62048ac5037b3fd4320f3eb4dea7b639d Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Tue, 10 Sep 2019 10:52:57 +0200 Subject: 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 --- sal/osl/unx/uunxapi.cxx | 74 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 19 deletions(-) (limited to 'sal/osl/unx/uunxapi.cxx') 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 #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 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 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(rp)), - osl_getThreadTextEncoding()); + ppstrResolvedName = fromOString(OString(static_cast(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 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; -- cgit