diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2017-09-25 08:59:28 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2017-09-27 06:24:24 +0200 |
commit | d32506e9f4ea604532bf5f4ba8a302b652aeaaa1 (patch) | |
tree | 2bd33f7917bd76d18f998eea531e4bdaa7d7eb54 /cppuhelper/source | |
parent | 892c719fffa06de4c7aeab497326cad7bae9e5c6 (diff) |
cppuhelper_detail_findSofficePath: use Unicode on Windows
On Windows, UTF-8 is never current locale encoding; so using 8-bit
strings will always fail for paths containing characters outside
of current codepage.
Also fix leaks caused by failing to release its result: previously
it could return either result of getenv (that shouldn't get freed),
or an allocated string, but never got freed; now the result is
always allocated and properly freed.
Change-Id: I8b255dea20040eec0572de2b34280749fe8f071c
Reviewed-on: https://gerrit.libreoffice.org/42743
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'cppuhelper/source')
-rw-r--r-- | cppuhelper/source/bootstrap.cxx | 13 | ||||
-rw-r--r-- | cppuhelper/source/findsofficepath.c | 64 |
2 files changed, 51 insertions, 26 deletions
diff --git a/cppuhelper/source/bootstrap.cxx b/cppuhelper/source/bootstrap.cxx index 55a0d244b724..923d0e925795 100644 --- a/cppuhelper/source/bootstrap.cxx +++ b/cppuhelper/source/bootstrap.cxx @@ -87,21 +87,28 @@ Reference< XComponentContext > SAL_CALL bootstrap() try { - char const * p1 = cppuhelper_detail_findSofficePath(); + auto* p1 = cppuhelper_detail_findSofficePath(); if (p1 == nullptr) { throw BootstrapException( "no soffice installation found!"); } rtl::OUString p2; - if (!rtl_convertStringToUString( +#if defined(_WIN32) + p2 = SAL_U(p1); + free(p1); +#else + bool bOk = rtl_convertStringToUString( &p2.pData, p1, std::strlen(p1), osl_getThreadTextEncoding(), (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | - RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))) + RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)); + free(p1); + if (!bOk) { throw BootstrapException( "bad characters in soffice installation path!"); } +#endif OUString path; if (osl::FileBase::getFileURLFromSystemPath(p2, path) != osl::FileBase::E_None) diff --git a/cppuhelper/source/findsofficepath.c b/cppuhelper/source/findsofficepath.c index 2a45f884ed71..f91f753c61eb 100644 --- a/cppuhelper/source/findsofficepath.c +++ b/cppuhelper/source/findsofficepath.c @@ -39,36 +39,42 @@ * @return the installation path or NULL, if no installation was found or * if an error occurred */ -static char* getPathFromRegistryKey( HKEY hroot, const char* subKeyName ) +static wchar_t* getPathFromRegistryKey( HKEY hroot, const wchar_t* subKeyName ) { HKEY hkey; DWORD type; - char* data = NULL; + wchar_t* data = NULL; DWORD size; /* open the specified registry key */ - if ( RegOpenKeyEx( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS ) + if ( RegOpenKeyExW( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS ) { return NULL; } /* find the type and size of the default value */ - if ( RegQueryValueEx( hkey, NULL, NULL, &type, NULL, &size) != ERROR_SUCCESS ) + if ( RegQueryValueExW( hkey, NULL, NULL, &type, NULL, &size) != ERROR_SUCCESS ) { RegCloseKey( hkey ); return NULL; } /* get memory to hold the default value */ - data = (char*) malloc( size ); + data = (wchar_t*) malloc( size + sizeof(wchar_t) ); /* read the default value */ - if ( RegQueryValueEx( hkey, NULL, NULL, &type, (LPBYTE) data, &size ) != ERROR_SUCCESS ) + if ( RegQueryValueExW( hkey, NULL, NULL, &type, (LPBYTE) data, &size ) != ERROR_SUCCESS ) { RegCloseKey( hkey ); + free( data ); return NULL; } + // According to https://msdn.microsoft.com/en-us/ms724911, If the data has the REG_SZ, + // REG_MULTI_SZ or REG_EXPAND_SZ type, the string may not have been stored with the + // proper terminating null characters + data[size / sizeof(wchar_t)] = 0; + /* release registry key handle */ RegCloseKey( hkey ); @@ -81,14 +87,22 @@ static char* getPathFromRegistryKey( HKEY hroot, const char* subKeyName ) * @return the installation path or NULL, if no installation was found or * if an error occurred */ -static char* platformSpecific() +static wchar_t* platformSpecific() { - const char* SUBKEYNAME = "Software\\LibreOffice\\UNO\\InstallPath"; + const wchar_t* UNOPATHVARNAME = L"UNO_PATH"; - char* path = NULL; + /* get the installation path from the UNO_PATH environment variable */ + wchar_t* env = _wgetenv(UNOPATHVARNAME); + + if (env && env[0]) + { + return wcsdup(env); + } + + const wchar_t* SUBKEYNAME = L"Software\\LibreOffice\\UNO\\InstallPath"; /* read the key's default value from HKEY_CURRENT_USER */ - path = getPathFromRegistryKey( HKEY_CURRENT_USER, SUBKEYNAME ); + wchar_t* path = getPathFromRegistryKey( HKEY_CURRENT_USER, SUBKEYNAME ); if ( path == NULL ) { @@ -115,13 +129,17 @@ static char* platformSpecific() */ static char* platformSpecific(void) { + const char* UNOPATHVARNAME = "UNO_PATH"; + + /* get the installation path from the UNO_PATH environment variable */ + char* env = getenv(UNOPATHVARNAME); + const int SEPARATOR = '/'; const char* PATHSEPARATOR = ":"; const char* PATHVARNAME = "PATH"; const char* APPENDIX = "/libreoffice"; char* path = NULL; - char* env = NULL; char* str = NULL; char* dir = NULL; char* sep = NULL; @@ -129,6 +147,11 @@ static char* platformSpecific(void) char buffer[PATH_MAX]; int pos; + if (env && env[0]) + { + return strdup(env); + } + /* get the value of the PATH environment variable */ env = getenv( PATHVARNAME ); if (env == NULL) @@ -184,19 +207,14 @@ static char* platformSpecific(void) #endif -char const* cppuhelper_detail_findSofficePath() +#if defined(_WIN32) +wchar_t* +#else +char* +#endif +cppuhelper_detail_findSofficePath() { - const char* UNOPATHVARNAME = "UNO_PATH"; - - char* path = NULL; - - /* get the installation path from the UNO_PATH environment variable */ - path = getenv( UNOPATHVARNAME ); - - if (!path || !path[0]) - path = platformSpecific(); - - return path; + return platformSpecific(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |