Skip to content

Commit

Permalink
Merge pull request #11639 from rouault/CPLFormFilenameSafe
Browse files Browse the repository at this point in the history
Safer CPL path functions (RFC 105 implementation)
  • Loading branch information
rouault authored Jan 17, 2025
2 parents f41af17 + 99dc672 commit 48b704b
Show file tree
Hide file tree
Showing 352 changed files with 4,172 additions and 3,396 deletions.
4 changes: 3 additions & 1 deletion alg/gdal_rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,9 @@ static bool RPCInverseTransformPoint(GDALRPCTransformInfo *psTransform,
if (psTransform->pszRPCInverseLog)
{
fpLog = VSIFOpenL(
CPLResetExtension(psTransform->pszRPCInverseLog, "csvt"), "wb");
CPLResetExtensionSafe(psTransform->pszRPCInverseLog, "csvt")
.c_str(),
"wb");
if (fpLog != nullptr)
{
VSIFPrintfL(fpLog, "Integer,Real,Real,Real,String,Real,Real\n");
Expand Down
16 changes: 10 additions & 6 deletions alg/gdalgeoloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1817,9 +1817,11 @@ void *GDALCreateGeoLocTransformerEx(GDALDatasetH hBaseDS,
papszGeolocationInfo, "X_DATASET_RELATIVE_TO_SOURCE", "NO")) &&
(hBaseDS != nullptr || pszSourceDataset))
{
CPLString osFilename = CPLProjectRelativeFilename(
CPLGetDirname(pszSourceDataset ? pszSourceDataset
: GDALGetDescription(hBaseDS)),
const CPLString osFilename = CPLProjectRelativeFilenameSafe(
CPLGetDirnameSafe(pszSourceDataset
? pszSourceDataset
: GDALGetDescription(hBaseDS))
.c_str(),
pszDSName);
psTransform->hDS_X =
GDALOpenShared(osFilename.c_str(), GA_ReadOnly);
Expand Down Expand Up @@ -1849,9 +1851,11 @@ void *GDALCreateGeoLocTransformerEx(GDALDatasetH hBaseDS,
papszGeolocationInfo, "Y_DATASET_RELATIVE_TO_SOURCE", "NO")) &&
(hBaseDS != nullptr || pszSourceDataset))
{
CPLString osFilename = CPLProjectRelativeFilename(
CPLGetDirname(pszSourceDataset ? pszSourceDataset
: GDALGetDescription(hBaseDS)),
const CPLString osFilename = CPLProjectRelativeFilenameSafe(
CPLGetDirnameSafe(pszSourceDataset
? pszSourceDataset
: GDALGetDescription(hBaseDS))
.c_str(),
pszDSName);
psTransform->hDS_Y =
GDALOpenShared(osFilename.c_str(), GA_ReadOnly);
Expand Down
12 changes: 6 additions & 6 deletions alg/gdalgeoloc_dataset_accessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ bool GDALGeoLocDatasetAccessors::AllocateBackMap()

// CPLResetExtension / CPLGenerateTempFilename generate short-lived strings,
// so store them in a long-lived std::string
const std::string osBackmapTmpFilename =
CPLResetExtension(CPLGenerateTempFilename(nullptr), "tif");
const std::string osBackmapTmpFilename = CPLResetExtensionSafe(
CPLGenerateTempFilenameSafe(nullptr).c_str(), "tif");
m_poBackmapTmpDataset = poDriver->Create(
osBackmapTmpFilename.c_str(), m_psTransform->nBackMapWidth,
m_psTransform->nBackMapHeight, 2, GDT_Float32,
Expand All @@ -124,8 +124,8 @@ bool GDALGeoLocDatasetAccessors::AllocateBackMap()

// CPLResetExtension / CPLGenerateTempFilename generate short-lived strings,
// so store them in a long-lived std::string
const std::string osBackmapWeightsTmpFilename =
CPLResetExtension(CPLGenerateTempFilename(nullptr), "tif");
const std::string osBackmapWeightsTmpFilename = CPLResetExtensionSafe(
CPLGenerateTempFilenameSafe(nullptr).c_str(), "tif");
m_poBackmapWeightsTmpDataset = poDriver->Create(
osBackmapWeightsTmpFilename.c_str(), m_psTransform->nBackMapWidth,
m_psTransform->nBackMapHeight, 1, GDT_Float32,
Expand Down Expand Up @@ -209,8 +209,8 @@ bool GDALGeoLocDatasetAccessors::LoadGeoloc(bool bIsRegularGrid)

// CPLResetExtension / CPLGenerateTempFilename generate short-lived
// strings, so store them in a long-lived std::string
const std::string osGeolocTmpFilename =
CPLResetExtension(CPLGenerateTempFilename(nullptr), "tif");
const std::string osGeolocTmpFilename = CPLResetExtensionSafe(
CPLGenerateTempFilenameSafe(nullptr).c_str(), "tif");
m_poGeolocTmpDataset =
poDriver->Create(osGeolocTmpFilename.c_str(), nXSize, nYSize, 2,
GDT_Float64, m_aosGTiffCreationOptions.List());
Expand Down
2 changes: 1 addition & 1 deletion alg/gdalproximity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ CPLErr CPL_STDCALL GDALComputeProximity(GDALRasterBandH hSrcBand,
eErr = CE_Failure;
goto end;
}
CPLString osTmpFile = CPLGenerateTempFilename("proximity");
CPLString osTmpFile = CPLGenerateTempFilenameSafe("proximity");
hWorkProximityDS = GDALCreate(hDriver, osTmpFile, nXSize, nYSize, 1,
GDT_Float32, nullptr);
if (hWorkProximityDS == nullptr)
Expand Down
2 changes: 1 addition & 1 deletion alg/rasterfill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ CPLErr CPL_STDCALL GDALFillNodata(GDALRasterBandH hTargetBand,
aosWorkFileOptions.SetNameValue("BIGTIFF", "IF_SAFER");
}

const CPLString osTmpFile = CPLGenerateTempFilename("");
const CPLString osTmpFile = CPLGenerateTempFilenameSafe("");

std::unique_ptr<GDALDataset> poTmpMaskDS;
if (hMaskBand == nullptr)
Expand Down
13 changes: 8 additions & 5 deletions apps/dumpoverviews.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,17 +134,19 @@ int main(int argc, char **argv)
/* --------------------------------------------------------------------
*/
CPLString osFilename;
osFilename.Printf("%s_%d_%d.tif", CPLGetBasename(pszSrcFilename),
osFilename.Printf("%s_%d_%d.tif",
CPLGetBasenameSafe(pszSrcFilename).c_str(),
iBand + 1, iOverview);
if (!DumpBand(hSrcDS, hSrcOver, osFilename))
bRet = false;

if (bMasks)
{
CPLString osMaskFilename;
osMaskFilename.Printf("%s_%d_%d_mask.tif",
CPLGetBasename(pszSrcFilename), iBand + 1,
iOverview);
osMaskFilename.Printf(
"%s_%d_%d_mask.tif",
CPLGetBasenameSafe(pszSrcFilename).c_str(), iBand + 1,
iOverview);
if (!DumpBand(hSrcDS, GDALGetMaskBand(hSrcOver),
osMaskFilename))
bRet = false;
Expand All @@ -159,7 +161,8 @@ int main(int argc, char **argv)
if (bMasks)
{
CPLString osFilename;
osFilename.Printf("%s_%d_mask.tif", CPLGetBasename(pszSrcFilename),
osFilename.Printf("%s_%d_mask.tif",
CPLGetBasenameSafe(pszSrcFilename).c_str(),
iBand + 1);
if (!DumpBand(hSrcDS, GDALGetMaskBand(hBaseBand), osFilename))
bRet = false;
Expand Down
3 changes: 2 additions & 1 deletion apps/gdal_contour.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,8 @@ MAIN_START(argc, argv)
{
CPLError(CE_Warning, CPLE_AppDefined,
"Several drivers matching %s extension. Using %s",
CPLGetExtension(sOptions.aosDestFilename.c_str()),
CPLGetExtensionSafe(sOptions.aosDestFilename.c_str())
.c_str(),
aoDrivers[0].c_str());
}
osFormat = aoDrivers[0];
Expand Down
9 changes: 5 additions & 4 deletions apps/gdal_footprint_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,8 @@ GetOutputLayerAndUpdateDstDS(const char *pszDest, GDALDatasetH &hDstDS,
{
CPLError(CE_Warning, CPLE_AppDefined,
"Several drivers matching %s extension. Using %s",
CPLGetExtension(pszDest), aoDrivers[0].c_str());
CPLGetExtensionSafe(pszDest).c_str(),
aoDrivers[0].c_str());
}
osFormat = aoDrivers[0];
}
Expand Down Expand Up @@ -633,7 +634,7 @@ GetOutputLayerAndUpdateDstDS(const char *pszDest, GDALDatasetH &hDstDS,
if (poDstDS->GetDriver() &&
EQUAL(poDstDS->GetDriver()->GetDescription(), "ESRI Shapefile"))
{
osDestLayerName = CPLGetBasename(pszDest);
osDestLayerName = CPLGetBasenameSafe(pszDest);
}
else
{
Expand Down Expand Up @@ -1187,8 +1188,8 @@ static bool GDALFootprintProcess(GDALDataset *poSrcDS, OGRLayer *poDstLayer,
char *pszCurDir = CPLGetCurrentDir();
if (pszCurDir)
{
osFilename = CPLProjectRelativeFilename(pszCurDir,
osFilename.c_str());
osFilename = CPLProjectRelativeFilenameSafe(
pszCurDir, osFilename.c_str());
CPLFree(pszCurDir);
}
}
Expand Down
13 changes: 7 additions & 6 deletions apps/gdal_translate_bin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,12 @@ MAIN_START(argc, argv)
char *pszSubDest = static_cast<char *>(
CPLMalloc(strlen(sOptionsForBinary.osDest.c_str()) + 32));

CPLString osPath = CPLGetPath(sOptionsForBinary.osDest.c_str());
CPLString osBasename =
CPLGetBasename(sOptionsForBinary.osDest.c_str());
CPLString osExtension =
CPLGetExtension(sOptionsForBinary.osDest.c_str());
const CPLString osPath =
CPLGetPathSafe(sOptionsForBinary.osDest.c_str());
const CPLString osBasename =
CPLGetBasenameSafe(sOptionsForBinary.osDest.c_str());
const CPLString osExtension =
CPLGetExtensionSafe(sOptionsForBinary.osDest.c_str());
CPLString osTemp;

const char *pszFormat = nullptr;
Expand All @@ -226,7 +227,7 @@ MAIN_START(argc, argv)
char *pszSource =
CPLStrdup(strstr(papszSubdatasets[i], "=") + 1);
osTemp = CPLSPrintf(pszFormat, osBasename.c_str(), i / 2 + 1);
osTemp = CPLFormFilename(osPath, osTemp, osExtension);
osTemp = CPLFormFilenameSafe(osPath, osTemp, osExtension);
strcpy(pszSubDest, osTemp.c_str());
hDataset = GDALOpenEx(pszSource, GDAL_OF_RASTER, nullptr,
sOptionsForBinary.aosOpenOptions.List(),
Expand Down
7 changes: 4 additions & 3 deletions apps/gdalbuildvrt_bin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,10 @@ MAIN_START(argc, argv)
if (hDriver &&
!(EQUAL(GDALGetDriverShortName(hDriver), "VRT") ||
(EQUAL(GDALGetDriverShortName(hDriver), "API_PROXY") &&
EQUAL(
CPLGetExtension(sOptionsForBinary.osDstFilename.c_str()),
"VRT"))))
EQUAL(CPLGetExtensionSafe(
sOptionsForBinary.osDstFilename.c_str())
.c_str(),
"VRT"))))
{
fprintf(
stderr,
Expand Down
2 changes: 1 addition & 1 deletion apps/gdalbuildvrt_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1684,7 +1684,7 @@ static bool add_file_to_list(const char *filename, const char *tile_index,
CPLStringList &aosList)
{

if (EQUAL(CPLGetExtension(filename), "SHP"))
if (EQUAL(CPLGetExtensionSafe(filename).c_str(), "SHP"))
{
/* Handle gdaltindex Shapefile as a special case */
auto poDS = std::unique_ptr<GDALDataset>(GDALDataset::Open(filename));
Expand Down
2 changes: 1 addition & 1 deletion apps/gdaldem_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2321,7 +2321,7 @@ static CPLErr GDALGenerateVRTColorRelief(const char *pszDstFilename,
GDALGetBlockSize(hSrcBand, &nBlockXSize, &nBlockYSize);

int bRelativeToVRT = FALSE;
CPLString osPath = CPLGetPath(pszDstFilename);
const CPLString osPath = CPLGetPathSafe(pszDstFilename);
char *pszSourceFilename = CPLStrdup(CPLExtractRelativePath(
osPath.c_str(), GDALGetDescription(hSrcDataset), &bRelativeToVRT));

Expand Down
4 changes: 2 additions & 2 deletions apps/gdalmanage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ static void ProcessIdentifyTarget(const char *pszTarget,
if (EQUAL(papszSiblingList[i], "..") || EQUAL(papszSiblingList[i], "."))
continue;

CPLString osSubTarget =
CPLFormFilename(pszTarget, papszSiblingList[i], nullptr);
const CPLString osSubTarget =
CPLFormFilenameSafe(pszTarget, papszSiblingList[i], nullptr);

ProcessIdentifyTarget(osSubTarget, papszSiblingList, bRecursive,
bReportFailures, bForceRecurse);
Expand Down
2 changes: 1 addition & 1 deletion apps/gdalmdimtranslate_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1794,7 +1794,7 @@ GDALMultiDimTranslate(const char *pszDest, GDALDatasetH hDstDS, int nSrcCount,
{
if (osFormat.empty())
{
if (EQUAL(CPLGetExtension(pszDest), "nc"))
if (EQUAL(CPLGetExtensionSafe(pszDest).c_str(), "nc"))
osFormat = "netCDF";
else
osFormat = GetOutputDriverForRaster(pszDest);
Expand Down
11 changes: 6 additions & 5 deletions apps/gdaltindex_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,8 +458,8 @@ struct GDALTileIndexTileIterator
continue;
}

const std::string osFilename =
CPLFormFilename(osCurDir.c_str(), psEntry->pszName, nullptr);
const std::string osFilename = CPLFormFilenameSafe(
osCurDir.c_str(), psEntry->pszName, nullptr);
if (VSI_ISDIR(psEntry->nMode))
{
auto poSrcDS = std::unique_ptr<GDALDataset>(
Expand Down Expand Up @@ -607,7 +607,8 @@ GDALDatasetH GDALTileIndex(const char *pszDest, int nSrcCount,
{
CPLError(CE_Warning, CPLE_AppDefined,
"Several drivers matching %s extension. Using %s",
CPLGetExtension(pszDest), aoDrivers[0].c_str());
CPLGetExtensionSafe(pszDest).c_str(),
aoDrivers[0].c_str());
}
osFormat = aoDrivers[0];
}
Expand Down Expand Up @@ -647,7 +648,7 @@ GDALDatasetH GDALTileIndex(const char *pszDest, int nSrcCount,
if (EQUAL(osFormat.c_str(), "ESRI Shapefile") ||
VSIStat(pszDest, &sStat) == 0)
{
osLayerName = CPLGetBasename(pszDest);
osLayerName = CPLGetBasenameSafe(pszDest);
}
else
{
Expand Down Expand Up @@ -999,7 +1000,7 @@ GDALDatasetH GDALTileIndex(const char *pszDest, int nSrcCount,
CPLIsFilenameRelative(osSrcFilename.c_str()) &&
VSIStat(osSrcFilename.c_str(), &sStatBuf) == 0)
{
osFileNameToWrite = CPLProjectRelativeFilename(
osFileNameToWrite = CPLProjectRelativeFilenameSafe(
osCurrentPath.c_str(), osSrcFilename.c_str());
}
else
Expand Down
2 changes: 1 addition & 1 deletion apps/gdaltorture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ static void ProcessTortureTarget(const char *pszTarget, char **papszSiblingList,
continue;

const CPLString osSubTarget =
CPLFormFilename(pszTarget, papszSiblingList[i], nullptr);
CPLFormFilenameSafe(pszTarget, papszSiblingList[i], nullptr);

ProcessTortureTarget(osSubTarget, papszSiblingList, bRecursive,
bReportFailures, bReadWriteOperations);
Expand Down
2 changes: 1 addition & 1 deletion apps/gdalwarp_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,7 @@ static bool CheckOptions(const char *pszDest, GDALDatasetH hDstDS,
}

if ((psOptions->osFormat.empty() &&
EQUAL(CPLGetExtension(pszDest), "VRT")) ||
EQUAL(CPLGetExtensionSafe(pszDest).c_str(), "VRT")) ||
(EQUAL(psOptions->osFormat.c_str(), "VRT")))
{
if (hDstDS != nullptr)
Expand Down
30 changes: 18 additions & 12 deletions apps/gnmmanage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,25 +507,27 @@ MAIN_START(nArgc, papszArgv)
}
else if (stOper == op_create)
{
const char *pszPath;
const char *pszNetworkName = CSLFetchNameValue(papszDSCO, GNM_MD_NAME);
std::string osPath;
std::string osNetworkName =
CSLFetchNameValueDef(papszDSCO, GNM_MD_NAME, "");

if (pszDataSource == nullptr)
Usage(true, "No network dataset provided");

// the DSCO have priority on input keys
if (nullptr == pszNetworkName)
if (osNetworkName.empty())
{
pszPath = CPLGetPath(pszDataSource);
pszNetworkName = CPLGetBasename(pszDataSource);
papszDSCO = CSLAddNameValue(papszDSCO, GNM_MD_NAME, pszNetworkName);
osPath = CPLGetPathSafe(pszDataSource);
osNetworkName = CPLGetBasenameSafe(pszDataSource);
papszDSCO =
CSLAddNameValue(papszDSCO, GNM_MD_NAME, osNetworkName.c_str());
}
else
{
pszPath = pszDataSource;
osPath = pszDataSource;
}

if (pszNetworkName == nullptr)
if (osNetworkName.empty())
Usage(true, "No dataset name provided");

const char *pszFinalSRS = CSLFetchNameValue(papszDSCO, GNM_MD_SRS);
Expand Down Expand Up @@ -553,16 +555,18 @@ MAIN_START(nArgc, papszArgv)
if (!CPLFetchBool(papszMD, GDAL_DCAP_GNM, false))
Usage(true, "not a GNM driver");

poDS = cpl::down_cast<GNMNetwork *>(
poDriver->Create(pszPath, 0, 0, 0, GDT_Unknown, papszDSCO));
poDS = cpl::down_cast<GNMNetwork *>(poDriver->Create(
osPath.c_str(), 0, 0, 0, GDT_Unknown, papszDSCO));

if (nullptr == poDS)
{
fprintf(
stderr,
"\nFAILURE: Failed to create network in a new dataset at "
"%s and with driver %s\n",
CPLFormFilename(pszPath, pszNetworkName, nullptr),
CPLFormFilenameSafe(osPath.c_str(), osNetworkName.c_str(),
nullptr)
.c_str(),
pszFormat);
nRet = 1;
}
Expand All @@ -571,7 +575,9 @@ MAIN_START(nArgc, papszArgv)
if (bQuiet == FALSE)
printf("\nNetwork created successfully in a "
"new dataset at %s\n",
CPLFormFilename(pszPath, pszNetworkName, nullptr));
CPLFormFilenameSafe(osPath.c_str(),
osNetworkName.c_str(), nullptr)
.c_str());
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion apps/nearblack_lib_floodfill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,8 @@ bool GDALNearblackFloodFillAlg::Process()
}
else
{
osVisitedDataset = CPLGenerateTempFilename(osVisitedDataset.c_str());
osVisitedDataset =
CPLGenerateTempFilenameSafe(osVisitedDataset.c_str());
}
CPLStringList aosOptions;
if (strcmp(pszTmpDriver, "GTiff") == 0)
Expand Down
Loading

0 comments on commit 48b704b

Please sign in to comment.