diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2011-09-27 10:06:54 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2011-09-27 10:10:55 +0200 |
commit | 193715bbf0e59256fd8da7ebd8dc5eb937615281 (patch) | |
tree | e268a2f2623b7ebd1ac03e71d763d9ab84952167 /sal | |
parent | 04b8b4fbbb4b7f72f33d0b76b86945cb98c4ecd9 (diff) |
FullTextEncodingDataSingleton must not call itself recursively.
Happened on non-standard locales (like hu_HU on Linux) when osl_loadModuleRelative
wanted to access non-standard text encodings.
For Windows, the fix is still only a "TODO: FIXME" dummy.
Diffstat (limited to 'sal')
-rw-r--r-- | sal/inc/osl/module.h | 24 | ||||
-rw-r--r-- | sal/inc/osl/module.hxx | 15 | ||||
-rw-r--r-- | sal/osl/unx/module.c | 168 | ||||
-rw-r--r-- | sal/osl/w32/module.cxx | 6 | ||||
-rw-r--r-- | sal/textenc/textenc.cxx | 12 |
5 files changed, 144 insertions, 81 deletions
diff --git a/sal/inc/osl/module.h b/sal/inc/osl/module.h index c103e41af7eb..67842325eb62 100644 --- a/sal/inc/osl/module.h +++ b/sal/inc/osl/module.h @@ -102,6 +102,30 @@ oslModule SAL_CALL osl_loadModuleAscii(const sal_Char *pModuleName, sal_Int32 nR oslModule SAL_CALL osl_loadModuleRelative( oslGenericFunction baseModule, rtl_uString * relativePath, sal_Int32 mode); +/** Load a module located relative to some other module. + + @param baseModule + must point to a function that is part of the code of some loaded module; + must not be NULL. + + @param relativePath + a relative URL containing only ASCII (0x01--7F) characters; must not be + NULL. + + @param mode + the SAL_LOADMODULE_xxx flags. + + @return + a non-NULL handle to the loaded module, or NULL if an error occurred. + + @since LibreOffice 3.5 +*/ +oslModule SAL_CALL osl_loadModuleRelativeAscii( + oslGenericFunction baseModule, char const * relativePath, sal_Int32 mode); + /* This function is guaranteed not to call into + FullTextEncodingDataSingleton in sal/textenc/textenc.cxx, so can be used + in its implementation without running into circles. */ + /** Retrieve the handle of an already loaded module. This function can be used to search for a function symbol in the process address space. diff --git a/sal/inc/osl/module.hxx b/sal/inc/osl/module.hxx index cfc1c5e02fc1..3ece623d1aa9 100644 --- a/sal/inc/osl/module.hxx +++ b/sal/inc/osl/module.hxx @@ -102,6 +102,16 @@ public: return is(); } + /// @since LibreOffice 3.5 + sal_Bool SAL_CALL loadRelative( + oslGenericFunction baseModule, char const * relativePath, + sal_Int32 mode = SAL_LOADMODULE_DEFAULT) + { + unload(); + m_Module = osl_loadModuleRelativeAscii(baseModule, relativePath, mode); + return is(); + } + void SAL_CALL unload() { if (m_Module) @@ -144,6 +154,11 @@ public: return ( osl_getFunctionSymbol( m_Module, ustrFunctionSymbolName.pData ) ); } + /// @since LibreOffice 3.5 + oslGenericFunction SAL_CALL getFunctionSymbol(char const * name) const { + return osl_getAsciiFunctionSymbol(m_Module, name); + } + operator oslModule() const { return m_Module; diff --git a/sal/osl/unx/module.c b/sal/osl/unx/module.c index 63fbc20b68b2..7db80117604a 100644 --- a/sal/osl/unx/module.c +++ b/sal/osl/unx/module.c @@ -46,6 +46,69 @@ /* implemented in file.c */ extern int UnicodeToText(char *, size_t, const sal_Unicode *, sal_Int32); +static sal_Bool getModulePathFromAddress(void * address, rtl_String ** path) { + sal_Bool result = sal_False; +/* Bah, we do want to use dladdr here also on iOS, I think? */ +#if !defined(NO_DL_FUNCTIONS) || defined(IOS) +#if defined(AIX) + int i; + int size = 4 * 1024; + char *buf, *filename=NULL; + struct ld_info *lp; + + if ((buf = malloc(size)) == NULL) + return result; + + while((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) + { + size += 4 * 1024; + if ((buf = malloc(size)) == NULL) + break; + } + + lp = (struct ld_info*) buf; + while (lp) + { + unsigned long start = (unsigned long)lp->ldinfo_dataorg; + unsigned long end = start + lp->ldinfo_datasize; + if (start <= (unsigned long)address && end > (unsigned long)address) + { + filename = lp->ldinfo_filename; + break; + } + if (!lp->ldinfo_next) + break; + lp = (struct ld_info*) ((char *) lp + lp->ldinfo_next); + } + + if (filename) + { + rtl_string_newFromStr(path, filename); + result = sal_True; + } + else + { + result = sal_False; + } + + free(buf); +#else + Dl_info dl_info; + + if ((result = dladdr(address, &dl_info)) != 0) + { + rtl_string_newFromStr(path, dl_info.dli_fname); + result = sal_True; + } + else + { + result = sal_False; + } +#endif +#endif + return result; +} + /*****************************************************************************/ /* osl_loadModule */ /*****************************************************************************/ @@ -104,6 +167,34 @@ oslModule SAL_CALL osl_loadModuleAscii(const sal_Char *pModuleName, sal_Int32 nR return NULL; } +oslModule osl_loadModuleRelativeAscii( + oslGenericFunction baseModule, char const * relativePath, sal_Int32 mode) +{ + OSL_ASSERT(relativePath != NULL); + if (relativePath[0] == '/') { + return osl_loadModuleAscii(relativePath, mode); + } else { + rtl_String * path = NULL; + rtl_String * suffix = NULL; + oslModule module; + if (!getModulePathFromAddress(baseModule, &path)) { + return NULL; + } + rtl_string_newFromStr_WithLength( + &path, path->buffer, + (rtl_str_lastIndexOfChar_WithLength(path->buffer, path->length, '/') + + 1)); + /* cut off everything after the last slash; should the original path + contain no slash, the resulting path is the empty string */ + rtl_string_newFromStr(&suffix, relativePath); + rtl_string_newConcat(&path, path, suffix); + rtl_string_release(suffix); + module = osl_loadModuleAscii(path->buffer, mode); + rtl_string_release(path); + return module; + } +} + /*****************************************************************************/ /* osl_getModuleHandle */ /*****************************************************************************/ @@ -209,51 +300,19 @@ osl_getFunctionSymbol(oslModule module, rtl_uString *puFunctionSymbolName) sal_Bool SAL_CALL osl_getModuleURLFromAddress(void * addr, rtl_uString ** ppLibraryUrl) { sal_Bool result = sal_False; -/* Bah, we do want to use dladdr here also on iOS, I think? */ -#if !defined(NO_DL_FUNCTIONS) || defined(IOS) -#if defined(AIX) - int i; - int size = 4 * 1024; - char *buf, *filename=NULL; - struct ld_info *lp; - - if ((buf = malloc(size)) == NULL) - return result; - - while((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) - { - size += 4 * 1024; - if ((buf = malloc(size)) == NULL) - break; - } - - lp = (struct ld_info*) buf; - while (lp) - { - unsigned long start = (unsigned long)lp->ldinfo_dataorg; - unsigned long end = start + lp->ldinfo_datasize; - if (start <= (unsigned long)addr && end > (unsigned long)addr) - { - filename = lp->ldinfo_filename; - break; - } - if (!lp->ldinfo_next) - break; - lp = (struct ld_info*) ((char *) lp + lp->ldinfo_next); - } - - if (filename) + rtl_String * path = NULL; + if (getModulePathFromAddress(addr, &path)) { rtl_uString * workDir = NULL; osl_getProcessWorkingDir(&workDir); if (workDir) { #if OSL_DEBUG_LEVEL > 1 - OSL_TRACE("module.c::osl_getModuleURLFromAddress - %s", filename); + OSL_TRACE("module.c::osl_getModuleURLFromAddress - %s", path->buffer); #endif rtl_string2UString(ppLibraryUrl, - filename, - strlen(filename), + path->buffer, + path->length, osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS); @@ -268,41 +327,8 @@ sal_Bool SAL_CALL osl_getModuleURLFromAddress(void * addr, rtl_uString ** ppLibr { result = sal_False; } + rtl_string_release(path); } - - free(buf); -#else - Dl_info dl_info; - - if ((result = dladdr(addr, &dl_info)) != 0) - { - rtl_uString * workDir = NULL; - osl_getProcessWorkingDir(&workDir); - if (workDir) - { -#if OSL_DEBUG_LEVEL > 1 - OSL_TRACE("module.c::osl_getModuleURLFromAddress - %s", dl_info.dli_fname); -#endif - rtl_string2UString(ppLibraryUrl, - dl_info.dli_fname, - strlen(dl_info.dli_fname), - osl_getThreadTextEncoding(), - OSTRING_TO_OUSTRING_CVTFLAGS); - - OSL_ASSERT(*ppLibraryUrl != NULL); - osl_getFileURLFromSystemPath(*ppLibraryUrl, ppLibraryUrl); - osl_getAbsoluteFileURL(workDir, *ppLibraryUrl, ppLibraryUrl); - - rtl_uString_release(workDir); - result = sal_True; - } - else - { - result = sal_False; - } - } -#endif -#endif return result; } diff --git a/sal/osl/w32/module.cxx b/sal/osl/w32/module.cxx index b9841ad1e4bd..07f750e49724 100644 --- a/sal/osl/w32/module.cxx +++ b/sal/osl/w32/module.cxx @@ -138,6 +138,12 @@ oslModule SAL_CALL osl_loadModuleAscii(const sal_Char *pModuleName, sal_Int32 nR return ret; } +oslModule osl_loadModuleRelativeAscii( + oslGenericFunction, char const * relativePath, sal_Int32 mode) +{ + return osl_loadModuleAscii(relativePath, mode); //TODO: FIXME +} + /*****************************************************************************/ /* osl_getModuleHandle */ /*****************************************************************************/ diff --git a/sal/textenc/textenc.cxx b/sal/textenc/textenc.cxx index 7c71284f3f64..c3f3bdc00768 100644 --- a/sal/textenc/textenc.cxx +++ b/sal/textenc/textenc.cxx @@ -129,20 +129,12 @@ void SAL_CALL thisModule() {} class FullTextEncodingData: private boost::noncopyable { public: FullTextEncodingData() { - if (!module_.loadRelative( - &thisModule, - rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - SAL_MODULENAME("sal_textenc"))))) - { + if (!module_.loadRelative(&thisModule, SAL_MODULENAME("sal_textenc"))) { OSL_TRACE("Loading sal_textenc library failed"); std::abort(); } function_ = reinterpret_cast< TextEncodingFunction * >( - module_.getFunctionSymbol( - rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "sal_getFullTextEncodingData")))); + module_.getFunctionSymbol("sal_getFullTextEncodingData")); if (function_ == 0) { OSL_TRACE( "Obtaining sal_getFullTextEncodingData fuction from sal_textenc" |