From db4544420fdd7f2504bde88a1f68846e8ba870ed Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 19 Feb 2024 22:41:17 +0100 Subject: [PATCH] VRTDerivedRasterBand: avoid potential initialization order fiasco (fixes #2884) --- frmts/vrt/vrtdataset.h | 2 +- frmts/vrt/vrtderivedrasterband.cpp | 35 ++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/frmts/vrt/vrtdataset.h b/frmts/vrt/vrtdataset.h index 439f3341f0db..aa6e352b296e 100644 --- a/frmts/vrt/vrtdataset.h +++ b/frmts/vrt/vrtdataset.h @@ -909,7 +909,7 @@ class CPL_DLL VRTDerivedRasterBand CPL_NON_FINAL : public VRTSourcedRasterBand GDALDerivedPixelFuncWithArgs pfnPixelFunc, const char *pszMetadata); - static std::pair * + static const std::pair * GetPixelFunction(const char *pszFuncNameIn); void SetPixelFunctionName(const char *pszFuncNameIn); diff --git a/frmts/vrt/vrtderivedrasterband.cpp b/frmts/vrt/vrtderivedrasterband.cpp index b69360ef58ad..f264826c4d6a 100644 --- a/frmts/vrt/vrtderivedrasterband.cpp +++ b/frmts/vrt/vrtderivedrasterband.cpp @@ -50,10 +50,6 @@ using namespace GDALPy; #define GDAL_VRT_ENABLE_PYTHON_DEFAULT "TRUSTED_MODULES" #endif -static std::map> - osMapPixelFunction; - /* Flags for getting buffers */ #define PyBUF_WRITABLE 0x0001 #define PyBUF_FORMAT 0x0004 @@ -231,6 +227,20 @@ void VRTDerivedRasterBand::Cleanup() { } +/************************************************************************/ +/* GetGlobalMapPixelFunction() */ +/************************************************************************/ + +static std::map> & +GetGlobalMapPixelFunction() +{ + static std::map> + gosMapPixelFunction; + return gosMapPixelFunction; +} + /************************************************************************/ /* AddPixelFunction() */ /************************************************************************/ @@ -261,7 +271,7 @@ CPLErr CPL_STDCALL GDALAddDerivedBandPixelFunc( return CE_None; } - osMapPixelFunction[pszName] = { + GetGlobalMapPixelFunction()[pszName] = { [pfnNewFunction](void **papoSources, int nSources, void *pData, int nBufXSize, int nBufYSize, GDALDataType eSrcType, GDALDataType eBufType, int nPixelSpace, int nLineSpace, @@ -299,13 +309,13 @@ CPLErr CPL_STDCALL GDALAddDerivedBandPixelFuncWithArgs( const char *pszName, GDALDerivedPixelFuncWithArgs pfnNewFunction, const char *pszMetadata) { - if (pszName == nullptr || pszName[0] == '\0' || pfnNewFunction == nullptr) + if (!pszName || pszName[0] == '\0' || !pfnNewFunction) { return CE_None; } - osMapPixelFunction[pszName] = {pfnNewFunction, - pszMetadata != nullptr ? pszMetadata : ""}; + GetGlobalMapPixelFunction()[pszName] = {pfnNewFunction, + pszMetadata ? pszMetadata : ""}; return CE_None; } @@ -353,7 +363,7 @@ CPLErr VRTDerivedRasterBand::AddPixelFunction( * @return A derived band pixel function, or NULL if none have been * registered for pszFuncName. */ -std::pair * +const std::pair * VRTDerivedRasterBand::GetPixelFunction(const char *pszFuncNameIn) { if (pszFuncNameIn == nullptr || pszFuncNameIn[0] == '\0') @@ -361,9 +371,10 @@ VRTDerivedRasterBand::GetPixelFunction(const char *pszFuncNameIn) return nullptr; } - auto oIter = osMapPixelFunction.find(pszFuncNameIn); + const auto &oMapPixelFunction = GetGlobalMapPixelFunction(); + const auto oIter = oMapPixelFunction.find(pszFuncNameIn); - if (oIter == osMapPixelFunction.end()) + if (oIter == oMapPixelFunction.end()) return nullptr; return &(oIter->second); @@ -945,7 +956,7 @@ CPLErr VRTDerivedRasterBand::IRasterIO( } /* ---- Get pixel function for band ---- */ - std::pair *poPixelFunc = nullptr; + const std::pair *poPixelFunc = nullptr; std::vector> oAdditionalArgs; if (EQUAL(m_poPrivate->m_osLanguage, "C"))