diff options
author | Brad King <brad.king@kitware.com> | 2012-04-26 14:36:53 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2012-04-27 12:13:52 (GMT) |
commit | e48796b26b5b2b75401b48d21927b1d2912d4dca (patch) | |
tree | 6b088ca80eedcd8459ce8b36114956d85995563d /bootstrap | |
parent | b10c5cbb878af541f4ffa35a9e287c31743c6e97 (diff) | |
download | CMake-e48796b26b5b2b75401b48d21927b1d2912d4dca.zip CMake-e48796b26b5b2b75401b48d21927b1d2912d4dca.tar.gz CMake-e48796b26b5b2b75401b48d21927b1d2912d4dca.tar.bz2 |
KWSys: Fix SystemTools environment memory handling (#13156)
The SystemTools::PutEnv function tries to provide the "putenv" API
without leaking memory. However, the kwsysDeletingCharVector singleton
frees memory that may still be referenced by the environment table,
having been placed there by putenv. If any static destruction or
processing by an external tool happens after the singleton is destroyed
and accesses the environment it will read invalid memory.
Replace use of putenv with setenv/unsetenv when available. The latter
manage internal copies of the values passed instead of referencing the
original memory. When setenv/unsetenv are not available use putenv with
a singleton that removes its values from the environment before freeing
their memory. This requires an "unputenv" implementation. On at least
some platforms it must be written in terms of "putenv" because other
APIs are not available and direct modification of the "environ" global
is not safe (e.g. on Windows there is interaction with "wenviron").
Fortunately either putenv("A=") or putenv("A") will remove "A" from the
environment on these platforms. On other platforms fall back to direct
manipulation of "environ".
Also add UnPutEnv to the API and add a test for the behavior of both.
Diffstat (limited to 'bootstrap')
-rwxr-xr-x | bootstrap | 37 |
1 files changed, 34 insertions, 3 deletions
@@ -395,7 +395,6 @@ cmake_kwsys_config_replace_string () echo "${APPEND}" > "${OUTFILE}${_tmp}" cat "${INFILE}" | sed "/./ {s/\@KWSYS_NAMESPACE\@/cmsys/g; - s/@KWSYS_DO_NOT_CLEAN_PUTENV@/0/g; s/@KWSYS_BUILD_SHARED@/${KWSYS_BUILD_SHARED}/g; s/@KWSYS_LFS_AVAILABLE@/${KWSYS_LFS_AVAILABLE}/g; s/@KWSYS_LFS_REQUESTED@/${KWSYS_LFS_REQUESTED}/g; @@ -1039,6 +1038,9 @@ KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE=0 KWSYS_STL_HAS_ALLOCATOR_REBIND=0 KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT=0 KWSYS_STL_HAS_ALLOCATOR_OBJECTS=0 +KWSYS_CXX_HAS_SETENV=0 +KWSYS_CXX_HAS_UNSETENV=0 +KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=0 KWSYS_CXX_HAS_CSTDDEF=0 KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS=0 KWSYS_CXX_HAS_MEMBER_TEMPLATES=0 @@ -1050,6 +1052,33 @@ KWSYS_STL_STRING_HAVE_ISTREAM=1 KWSYS_STL_STRING_HAVE_OSTREAM=1 if cmake_try_run "${cmake_cxx_compiler}" \ + "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_SETENV" \ + "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then + KWSYS_CXX_HAS_SETENV=1 + echo "${cmake_cxx_compiler} has setenv" +else + echo "${cmake_cxx_compiler} does not have setenv" +fi + +if cmake_try_run "${cmake_cxx_compiler}" \ + "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_UNSETENV" \ + "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then + KWSYS_CXX_HAS_UNSETENV=1 + echo "${cmake_cxx_compiler} has unsetenv" +else + echo "${cmake_cxx_compiler} does not have unsetenv" +fi + +if cmake_try_run "${cmake_cxx_compiler}" \ + "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H" \ + "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then + KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=1 + echo "${cmake_cxx_compiler} has environ in stdlib.h" +else + echo "${cmake_cxx_compiler} does not have environ in stdlib.h" +fi + +if cmake_try_run "${cmake_cxx_compiler}" \ "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAVE_STD" \ "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then KWSYS_STL_HAVE_STD=1 @@ -1365,7 +1394,7 @@ cmake_replace_string "${cmake_source_dir}/Source/kwsys/kwsys_stl.hxx.in" \ cmake_replace_string "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_a" \ "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_b" KWSYS_NAMESPACE cmsys -for a in string vector map algorithm; do +for a in string vector set map algorithm; do cmake_replace_string "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_b" \ "${cmake_bootstrap_dir}/cmsys/stl/${a}" KWSYS_STL_HEADER ${a} done @@ -1396,6 +1425,7 @@ if [ "x${cmake_cxx_flags}" != "x" ]; then fi cmake_c_flags_String="-DKWSYS_STRING_C" +cmake_cxx_flags_SystemTools="-DKWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV} -DKWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV} -DKWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H}" cmake_c_flags="${cmake_c_flags}-I`cmake_escape \"${cmake_bootstrap_dir}\"` -I`cmake_escape \"${cmake_source_dir}/Source\"` \ -I`cmake_escape \"${cmake_bootstrap_dir}\"`" cmake_cxx_flags="${cmake_cxx_flags} -I`cmake_escape \"${cmake_bootstrap_dir}\"` -I`cmake_escape \"${cmake_source_dir}/Source\"` \ @@ -1421,8 +1451,9 @@ for a in ${KWSYS_C_SOURCES} ${KWSYS_C_MINGW_SOURCES}; do done for a in ${KWSYS_CXX_SOURCES}; do src=`cmake_escape "${cmake_source_dir}/Source/kwsys/${a}.cxx"` + src_flags=`eval echo \\${cmake_cxx_flags_\${a}}` echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile" - echo " ${cmake_cxx_compiler} ${cmake_cxx_flags} -DKWSYS_NAMESPACE=cmsys -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile" + echo " ${cmake_cxx_compiler} ${cmake_cxx_flags} -DKWSYS_NAMESPACE=cmsys ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile" done if ${cmake_system_mingw}; then src=`cmake_escape "${cmake_bootstrap_dir}/cmsysProcessFwd9xEnc.c"` |