From 9309d06b7310e8ffa64dc1ca2d3312646e7e693f Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Tue, 2 Aug 2022 16:18:30 -0500 Subject: [PATCH] BUG: Avoid dangerous use of putenv https://stackoverflow.com/a/54279521 While std::getenv is part of the C++ standard, the putenv function isn't. As you can see from the linked POSIX reference for putenv, it's argument is of type char *. This is very important, and one thing that differs between C and C++: In C a literal string can be passed to functions expecting char *. In C++ all literal strings are constant and can only be passed to functions expecting const char *. Use the itksys::Process::PutEnv wrapper that provides cross platform safe wrappers for setting/getting the environmental variables. --- Modules/Core/Common/src/itkObjectFactoryBase.cxx | 11 +++++------ .../Core/Common/test/itkObjectFactoryTest2.cxx | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Modules/Core/Common/src/itkObjectFactoryBase.cxx b/Modules/Core/Common/src/itkObjectFactoryBase.cxx index f89f5f31a3b..c3377d44723 100644 --- a/Modules/Core/Common/src/itkObjectFactoryBase.cxx +++ b/Modules/Core/Common/src/itkObjectFactoryBase.cxx @@ -34,6 +34,7 @@ #include "itkLightObject.h" #include "itkSingleton.h" #include "itkVersion.h" +#include "itksys/SystemTools.hxx" #include #include @@ -305,12 +306,9 @@ ObjectFactoryBase::LoadDynamicFactories() char PathSeparator = ':'; # endif - std::string LoadPath; - if (getenv("ITK_AUTOLOAD_PATH")) - { - LoadPath = getenv("ITK_AUTOLOAD_PATH"); - } - else + const std::string itk_autoload_env{ "ITK_AUTOLOAD_PATH" }; + std::string LoadPath; + if (!itksys::SystemTools::GetEnv(itk_autoload_env, LoadPath)) { return; } @@ -318,6 +316,7 @@ ObjectFactoryBase::LoadDynamicFactories() { return; } + std::string::size_type EndSeparatorPosition = 0; std::string::size_type StartSeparatorPosition = 0; diff --git a/Modules/Core/Common/test/itkObjectFactoryTest2.cxx b/Modules/Core/Common/test/itkObjectFactoryTest2.cxx index 5c28f1ee846..6e6e3e644d1 100644 --- a/Modules/Core/Common/test/itkObjectFactoryTest2.cxx +++ b/Modules/Core/Common/test/itkObjectFactoryTest2.cxx @@ -20,6 +20,7 @@ #include "itkRGBPixel.h" #include "itkTextOutput.h" // Needed to see warnings #include "itkTestingMacros.h" +#include "itksys/SystemTools.hxx" using myPointer = itk::ImportImageContainer::Pointer; bool @@ -118,10 +119,18 @@ itkObjectFactoryTest2(int argc, char * argv[]) #ifdef CMAKE_INTDIR path += std::string("/") + std::string(CMAKE_INTDIR); #endif + const std::string itk_autoload_env{ "ITK_AUTOLOAD_PATH" }; + const std::string myenv{ itk_autoload_env + "=" + path }; + itksys::SystemTools::PutEnv(myenv); + std::cout << "SetValue => " << myenv << std::endl; + std::string getmyenv; + if (!itksys::SystemTools::GetEnv(itk_autoload_env, getmyenv)) + { + std::cerr << "ERROR: Environmental variable not set as requested : " << itk_autoload_env << "!=" << path + << std::endl; + } + std::cout << "GetValue => " << itk_autoload_env + "=" + getmyenv << std::endl; - std::string myenv = std::string("ITK_AUTOLOAD_PATH=") + path; - std::cout << myenv << std::endl; - putenv(const_cast(myenv.c_str())); itk::ObjectFactoryBase::ReHash(); // List all registered factories