diff options
| author | Pali Rohár <pali.rohar@gmail.com> | 2019-05-23 20:23:58 +0200 |
|---|---|---|
| committer | Pali Rohár <pali.rohar@gmail.com> | 2019-05-23 20:23:58 +0200 |
| commit | 207311ceba4f8e2ebab27ead6e07dfecef392383 (patch) | |
| tree | 63a78a42a0318d25650d0106224e8320f1c43202 | |
| parent | 44589dba9c663eaeed5dbf55a02984133b9ab822 (diff) | |
| download | dlfcn-win32-207311ceba4f8e2ebab27ead6e07dfecef392383.tar.gz dlfcn-win32-207311ceba4f8e2ebab27ead6e07dfecef392383.tar.bz2 dlfcn-win32-207311ceba4f8e2ebab27ead6e07dfecef392383.zip | |
Correctly process and indicate error when file name is too long
| -rw-r--r-- | dlfcn.c | 102 |
1 files changed, 55 insertions, 47 deletions
| @@ -242,63 +242,71 @@ void *dlopen( const char *file, int mode ) | |||
| 242 | HANDLE hCurrentProc; | 242 | HANDLE hCurrentProc; |
| 243 | DWORD dwProcModsBefore, dwProcModsAfter; | 243 | DWORD dwProcModsBefore, dwProcModsAfter; |
| 244 | char lpFileName[MAX_PATH]; | 244 | char lpFileName[MAX_PATH]; |
| 245 | size_t i; | 245 | size_t i, len; |
| 246 | |||
| 247 | /* MSDN says backslashes *must* be used instead of forward slashes. */ | ||
| 248 | for( i = 0 ; i < sizeof(lpFileName) - 1 ; i ++ ) | ||
| 249 | { | ||
| 250 | if( !file[i] ) | ||
| 251 | break; | ||
| 252 | else if( file[i] == '/' ) | ||
| 253 | lpFileName[i] = '\\'; | ||
| 254 | else | ||
| 255 | lpFileName[i] = file[i]; | ||
| 256 | } | ||
| 257 | lpFileName[i] = '\0'; | ||
| 258 | |||
| 259 | hCurrentProc = GetCurrentProcess( ); | ||
| 260 | 246 | ||
| 261 | if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsBefore ) == 0 ) | 247 | len = strlen( file ); |
| 262 | dwProcModsBefore = 0; | ||
| 263 | 248 | ||
| 264 | /* POSIX says the search path is implementation-defined. | 249 | if( len >= sizeof( lpFileName ) ) |
| 265 | * LOAD_WITH_ALTERED_SEARCH_PATH is used to make it behave more closely | ||
| 266 | * to UNIX's search paths (start with system folders instead of current | ||
| 267 | * folder). | ||
| 268 | */ | ||
| 269 | hModule = LoadLibraryExA(lpFileName, NULL, | ||
| 270 | LOAD_WITH_ALTERED_SEARCH_PATH ); | ||
| 271 | |||
| 272 | if( !hModule ) | ||
| 273 | { | 250 | { |
| 274 | save_err_str( lpFileName ); | 251 | SetLastError( ERROR_FILENAME_EXCED_RANGE ); |
| 252 | save_err_str( file ); | ||
| 253 | hModule = NULL; | ||
| 275 | } | 254 | } |
| 276 | else | 255 | else |
| 277 | { | 256 | { |
| 278 | if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsAfter ) == 0 ) | 257 | /* MSDN says backslashes *must* be used instead of forward slashes. */ |
| 279 | dwProcModsAfter = 0; | 258 | for( i = 0; i < len; i++ ) |
| 280 | 259 | { | |
| 281 | /* If the object was loaded with RTLD_LOCAL, add it to list of local | 260 | if( file[i] == '/' ) |
| 282 | * objects, so that its symbols cannot be retrieved even if the handle for | 261 | lpFileName[i] = '\\'; |
| 283 | * the original program file is passed. POSIX says that if the same | 262 | else |
| 284 | * file is specified in multiple invocations, and any of them are | 263 | lpFileName[i] = file[i]; |
| 285 | * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the | 264 | } |
| 286 | * symbols will remain global. If number of loaded modules was not | 265 | lpFileName[len] = '\0'; |
| 287 | * changed after calling LoadLibraryEx(), it means that library was | 266 | |
| 288 | * already loaded. | 267 | hCurrentProc = GetCurrentProcess( ); |
| 268 | |||
| 269 | if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsBefore ) == 0 ) | ||
| 270 | dwProcModsBefore = 0; | ||
| 271 | |||
| 272 | /* POSIX says the search path is implementation-defined. | ||
| 273 | * LOAD_WITH_ALTERED_SEARCH_PATH is used to make it behave more closely | ||
| 274 | * to UNIX's search paths (start with system folders instead of current | ||
| 275 | * folder). | ||
| 289 | */ | 276 | */ |
| 290 | if( (mode & RTLD_LOCAL) && dwProcModsBefore != dwProcModsAfter ) | 277 | hModule = LoadLibraryExA( lpFileName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH ); |
| 278 | |||
| 279 | if( !hModule ) | ||
| 291 | { | 280 | { |
| 292 | if( !local_add( hModule ) ) | 281 | save_err_str( lpFileName ); |
| 293 | { | ||
| 294 | save_err_str( lpFileName ); | ||
| 295 | FreeLibrary( hModule ); | ||
| 296 | hModule = NULL; | ||
| 297 | } | ||
| 298 | } | 282 | } |
| 299 | else if( !(mode & RTLD_LOCAL) && dwProcModsBefore == dwProcModsAfter ) | 283 | else |
| 300 | { | 284 | { |
| 301 | local_rem( hModule ); | 285 | if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsAfter ) == 0 ) |
| 286 | dwProcModsAfter = 0; | ||
| 287 | |||
| 288 | /* If the object was loaded with RTLD_LOCAL, add it to list of local | ||
| 289 | * objects, so that its symbols cannot be retrieved even if the handle for | ||
| 290 | * the original program file is passed. POSIX says that if the same | ||
| 291 | * file is specified in multiple invocations, and any of them are | ||
| 292 | * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the | ||
| 293 | * symbols will remain global. If number of loaded modules was not | ||
| 294 | * changed after calling LoadLibraryEx(), it means that library was | ||
| 295 | * already loaded. | ||
| 296 | */ | ||
| 297 | if( (mode & RTLD_LOCAL) && dwProcModsBefore != dwProcModsAfter ) | ||
| 298 | { | ||
| 299 | if( !local_add( hModule ) ) | ||
| 300 | { | ||
| 301 | save_err_str( lpFileName ); | ||
| 302 | FreeLibrary( hModule ); | ||
| 303 | hModule = NULL; | ||
| 304 | } | ||
| 305 | } | ||
| 306 | else if( !(mode & RTLD_LOCAL) && dwProcModsBefore == dwProcModsAfter ) | ||
| 307 | { | ||
| 308 | local_rem( hModule ); | ||
| 309 | } | ||
| 302 | } | 310 | } |
| 303 | } | 311 | } |
| 304 | } | 312 | } |
