@@ -279,6 +279,19 @@ static bool conc_path_file_and_check(char *buffer, char *printbuffer, size_t pri
279
279
return false ;
280
280
}
281
281
282
+ // Frees all memory allocated on the heap for the
283
+ // supplied array of arrays of chars (a), where n
284
+ // is the number of elements in the array.
285
+ static void free_array_of_char_arrays (char ** a, size_t n) {
286
+ while (n > 0 ) {
287
+ n--;
288
+ if (a[n] != NULL ) {
289
+ FREE_C_HEAP_ARRAY (char , a[n]);
290
+ }
291
+ }
292
+ FREE_C_HEAP_ARRAY (char *, a);
293
+ }
294
+
282
295
bool os::dll_locate_lib (char *buffer, size_t buflen,
283
296
const char * pname, const char * fname) {
284
297
bool retval = false ;
@@ -299,10 +312,10 @@ bool os::dll_locate_lib(char *buffer, size_t buflen,
299
312
}
300
313
} else if (strchr (pname, *os::path_separator ()) != NULL ) {
301
314
// A list of paths. Search for the path that contains the library.
302
- int n;
303
- char ** pelements = split_path (pname, &n);
315
+ size_t n;
316
+ char ** pelements = split_path (pname, &n, fullfnamelen );
304
317
if (pelements != NULL ) {
305
- for (int i = 0 ; i < n; i++) {
318
+ for (size_t i = 0 ; i < n; i++) {
306
319
char * path = pelements[i];
307
320
// Really shouldn't be NULL, but check can't hurt.
308
321
size_t plen = (path == NULL ) ? 0 : strlen (path);
@@ -314,12 +327,7 @@ bool os::dll_locate_lib(char *buffer, size_t buflen,
314
327
if (retval) break ;
315
328
}
316
329
// Release the storage allocated by split_path.
317
- for (int i = 0 ; i < n; i++) {
318
- if (pelements[i] != NULL ) {
319
- FREE_C_HEAP_ARRAY (char , pelements[i]);
320
- }
321
- }
322
- FREE_C_HEAP_ARRAY (char *, pelements);
330
+ free_array_of_char_arrays (pelements, n);
323
331
}
324
332
} else {
325
333
// A definite path.
@@ -1335,17 +1343,22 @@ bool os::set_boot_path(char fileSep, char pathSep) {
1335
1343
return false ;
1336
1344
}
1337
1345
1338
- /*
1339
- * Splits a path, based on its separator, the number of
1340
- * elements is returned back in n.
1341
- * It is the callers responsibility to:
1342
- * a> check the value of n, and n may be 0.
1343
- * b> ignore any empty path elements
1344
- * c> free up the data.
1345
- */
1346
- char ** os::split_path (const char * path, int * n) {
1347
- *n = 0 ;
1348
- if (path == NULL || strlen (path) == 0 ) {
1346
+ // Splits a path, based on its separator, the number of
1347
+ // elements is returned back in "elements".
1348
+ // file_name_length is used as a modifier for each path's
1349
+ // length when compared to JVM_MAXPATHLEN. So if you know
1350
+ // each returned path will have something appended when
1351
+ // in use, you can pass the length of that in
1352
+ // file_name_length, to ensure we detect if any path
1353
+ // exceeds the maximum path length once prepended onto
1354
+ // the sub-path/file name.
1355
+ // It is the callers responsibility to:
1356
+ // a> check the value of "elements", which may be 0.
1357
+ // b> ignore any empty path elements
1358
+ // c> free up the data.
1359
+ char ** os::split_path (const char * path, size_t * elements, size_t file_name_length) {
1360
+ *elements = (size_t )0 ;
1361
+ if (path == NULL || strlen (path) == 0 || file_name_length == (size_t )NULL ) {
1349
1362
return NULL ;
1350
1363
}
1351
1364
const char psepchar = *os::path_separator ();
@@ -1354,7 +1367,7 @@ char** os::split_path(const char* path, int* n) {
1354
1367
return NULL ;
1355
1368
}
1356
1369
strcpy (inpath, path);
1357
- int count = 1 ;
1370
+ size_t count = 1 ;
1358
1371
char * p = strchr (inpath, psepchar);
1359
1372
// Get a count of elements to allocate memory
1360
1373
while (p != NULL ) {
@@ -1363,20 +1376,23 @@ char** os::split_path(const char* path, int* n) {
1363
1376
p = strchr (p, psepchar);
1364
1377
}
1365
1378
char ** opath = (char **) NEW_C_HEAP_ARRAY (char *, count, mtInternal);
1366
- if (opath == NULL ) {
1367
- return NULL ;
1368
- }
1369
1379
1370
1380
// do the actual splitting
1371
1381
p = inpath;
1372
- for (int i = 0 ; i < count ; i++) {
1382
+ for (size_t i = 0 ; i < count ; i++) {
1373
1383
size_t len = strcspn (p, os::path_separator ());
1374
- if (len > JVM_MAXPATHLEN) {
1375
- return NULL ;
1384
+ if (len + file_name_length > JVM_MAXPATHLEN) {
1385
+ // release allocated storage before exiting the vm
1386
+ free_array_of_char_arrays (opath, i++);
1387
+ vm_exit_during_initialization (" The VM tried to use a path that exceeds the maximum path length for "
1388
+ " this system. Review path-containing parameters and properties, such as "
1389
+ " sun.boot.library.path, to identify potential sources for this path." );
1376
1390
}
1377
1391
// allocate the string and add terminator storage
1378
- char * s = (char *)NEW_C_HEAP_ARRAY (char , len + 1 , mtInternal);
1392
+ char * s = (char *)NEW_C_HEAP_ARRAY_RETURN_NULL (char , len + 1 , mtInternal);
1379
1393
if (s == NULL ) {
1394
+ // release allocated storage before returning null
1395
+ free_array_of_char_arrays (opath, i++);
1380
1396
return NULL ;
1381
1397
}
1382
1398
strncpy (s, p, len);
@@ -1385,7 +1401,7 @@ char** os::split_path(const char* path, int* n) {
1385
1401
p += len + 1 ;
1386
1402
}
1387
1403
FREE_C_HEAP_ARRAY (char , inpath);
1388
- *n = count;
1404
+ *elements = count;
1389
1405
return opath;
1390
1406
}
1391
1407
0 commit comments