Skip to content

Commit

Permalink
BUG: Avoid dangerous use of putenv
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
hjmjohnson committed Aug 2, 2022
1 parent 5b09d54 commit 9309d06
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 9 deletions.
11 changes: 5 additions & 6 deletions Modules/Core/Common/src/itkObjectFactoryBase.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "itkLightObject.h"
#include "itkSingleton.h"
#include "itkVersion.h"
#include "itksys/SystemTools.hxx"
#include <cstring>
#include <algorithm>

Expand Down Expand Up @@ -305,19 +306,17 @@ 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;
}
if (LoadPath.empty())
{
return;
}

std::string::size_type EndSeparatorPosition = 0;
std::string::size_type StartSeparatorPosition = 0;

Expand Down
15 changes: 12 additions & 3 deletions Modules/Core/Common/test/itkObjectFactoryTest2.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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<unsigned long, short>::Pointer;
bool
Expand Down Expand Up @@ -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<char *>(myenv.c_str()));
itk::ObjectFactoryBase::ReHash();

// List all registered factories
Expand Down

0 comments on commit 9309d06

Please sign in to comment.