aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPali Rohár <pali.rohar@gmail.com>2019-05-23 20:23:58 +0200
committerPali Rohár <pali.rohar@gmail.com>2019-05-23 20:23:58 +0200
commit207311ceba4f8e2ebab27ead6e07dfecef392383 (patch)
tree63a78a42a0318d25650d0106224e8320f1c43202
parent44589dba9c663eaeed5dbf55a02984133b9ab822 (diff)
downloaddlfcn-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.c102
1 files changed, 55 insertions, 47 deletions
diff --git a/dlfcn.c b/dlfcn.c
index 7fe4701..ec60423 100644
--- a/dlfcn.c
+++ b/dlfcn.c
@@ -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 }