@@ -452,15 +452,20 @@ char *VSIArchiveFilesystemHandler::SplitFilename(const char *pszFilename,
452
452
453
453
const std::vector<CPLString> oExtensions = GetExtensions ();
454
454
int nAttempts = 0 ;
455
- while (pszFilename[i])
455
+ // If we are called with pszFilename being one of the TLS buffers returned
456
+ // by cpl_path.cpp functions, then a call to Stat() in the loop (and its
457
+ // cascaded calls to other cpl_path.cpp functions) might lead to altering
458
+ // the buffer to be altered, hence take a copy
459
+ const std::string osFilenameCopy (pszFilename);
460
+ while (i < static_cast <int >(osFilenameCopy.size ()))
456
461
{
457
462
int nToSkip = 0 ;
458
463
459
464
for (std::vector<CPLString>::const_iterator iter = oExtensions.begin ();
460
465
iter != oExtensions.end (); ++iter)
461
466
{
462
467
const CPLString &osExtension = *iter;
463
- if (EQUALN (pszFilename + i, osExtension.c_str (),
468
+ if (EQUALN (osFilenameCopy. c_str () + i, osExtension.c_str (),
464
469
osExtension.size ()))
465
470
{
466
471
nToSkip = static_cast <int >(osExtension.size ());
@@ -470,7 +475,8 @@ char *VSIArchiveFilesystemHandler::SplitFilename(const char *pszFilename,
470
475
471
476
#ifdef DEBUG
472
477
// For AFL, so that .cur_input is detected as the archive filename.
473
- if (EQUALN (pszFilename + i, " .cur_input" , strlen (" .cur_input" )))
478
+ if (EQUALN (osFilenameCopy.c_str () + i, " .cur_input" ,
479
+ strlen (" .cur_input" )))
474
480
{
475
481
nToSkip = static_cast <int >(strlen (" .cur_input" ));
476
482
}
@@ -486,7 +492,7 @@ char *VSIArchiveFilesystemHandler::SplitFilename(const char *pszFilename,
486
492
break ;
487
493
}
488
494
VSIStatBufL statBuf;
489
- char *archiveFilename = CPLStrdup (pszFilename );
495
+ char *archiveFilename = CPLStrdup (osFilenameCopy. c_str () );
490
496
bool bArchiveFileExists = false ;
491
497
492
498
if (IsEitherSlash (archiveFilename[i + nToSkip]))
@@ -527,10 +533,11 @@ char *VSIArchiveFilesystemHandler::SplitFilename(const char *pszFilename,
527
533
528
534
if (bArchiveFileExists)
529
535
{
530
- if (IsEitherSlash (pszFilename[i + nToSkip]))
536
+ if (IsEitherSlash (osFilenameCopy[i + nToSkip]) &&
537
+ i + nToSkip + 1 < static_cast <int >(osFilenameCopy.size ()))
531
538
{
532
- osFileInArchive =
533
- CompactFilename (pszFilename + i + nToSkip + 1 );
539
+ osFileInArchive = CompactFilename (osFilenameCopy. c_str () +
540
+ i + nToSkip + 1 );
534
541
}
535
542
else
536
543
{
@@ -545,12 +552,22 @@ char *VSIArchiveFilesystemHandler::SplitFilename(const char *pszFilename,
545
552
osFileInArchive.pop_back ();
546
553
}
547
554
555
+ // Messy! Restore the TLS buffer if it has been altered
556
+ if (osFilenameCopy != pszFilename)
557
+ strcpy (const_cast <char *>(pszFilename),
558
+ osFilenameCopy.c_str ());
559
+
548
560
return archiveFilename;
549
561
}
550
562
CPLFree (archiveFilename);
551
563
}
552
564
i++;
553
565
}
566
+
567
+ // Messy! Restore the TLS buffer if it has been altered
568
+ if (osFilenameCopy != pszFilename)
569
+ strcpy (const_cast <char *>(pszFilename), osFilenameCopy.c_str ());
570
+
554
571
return nullptr ;
555
572
}
556
573
0 commit comments