From 9646dc324d10d11c5020e120fd732c3fee3e5257 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 29 Nov 2024 09:53:38 +0100 Subject: [PATCH] Make `getenv` thread-safe In order to return a non-owning pointer without memory leaks the function needs to use a static variable. When calling it from multiple threads there is a data race during the assignment (and conversion) to this variable. Fix by making it `thread_local`. Fixes #189 --- include/boost/nowide/cstdlib.hpp | 7 ++++++- src/cstdlib.cpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/boost/nowide/cstdlib.hpp b/include/boost/nowide/cstdlib.hpp index a48028a..cfdac7c 100644 --- a/include/boost/nowide/cstdlib.hpp +++ b/include/boost/nowide/cstdlib.hpp @@ -21,7 +21,12 @@ namespace nowide { /// /// \brief UTF-8 aware getenv. Returns 0 if the variable is not set. /// - /// This function is not thread safe or reenterable as defined by the standard library + /// The string pointed to shall not be modified by the program. + /// This function is thread-safe as long as no other thread modifies the host environment. + /// However subsequent calls to this function might overwrite the string pointed to. + /// + /// Warning: The returned pointer might only be valid for as long as the calling thread is alive. + /// So avoid passing it across thread boundaries. /// BOOST_NOWIDE_DECL char* getenv(const char* key); diff --git a/src/cstdlib.cpp b/src/cstdlib.cpp index ab0d445..76f0319 100644 --- a/src/cstdlib.cpp +++ b/src/cstdlib.cpp @@ -52,7 +52,7 @@ namespace boost { namespace nowide { char* getenv(const char* key) { - static stackstring value; + thread_local stackstring value; const wshort_stackstring name(key);