Skip to content

Commit 836cf31

Browse files
bpo-37931: Fix crash on OSX re-initializing os.environ (GH-15428)
On most platforms, the `environ` symbol is accessible everywhere. In a dylib on OSX, it's not easily accessible, you need to find it with _NSGetEnviron. The code was caching the *value* of environ. But a setenv() can change the value, leaving garbage at the old value. Fix: don't cache the value of environ, just read it every time. (cherry picked from commit 723f71a) Co-authored-by: Benoit Hudson <[email protected]>
1 parent c9f480d commit 836cf31

File tree

3 files changed

+9
-5
lines changed

3 files changed

+9
-5
lines changed

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,7 @@ Miro Hrončok
725725
Chiu-Hsiang Hsu
726726
Chih-Hao Huang
727727
Christian Hudon
728+
Benoît Hudson
728729
Lawrence Hudson
729730
Michael Hudson
730731
Jim Hugunin
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed a crash on OSX dynamic builds that occurred when re-initializing the
2+
posix module after a Py_Finalize if the environment had changed since the
3+
previous `import posix`. Patch by Benoît Hudson.

Modules/posixmodule.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,7 +1372,6 @@ win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
13721372
** man environ(7).
13731373
*/
13741374
#include <crt_externs.h>
1375-
static char **environ;
13761375
#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
13771376
extern char **environ;
13781377
#endif /* !_MSC_VER */
@@ -1390,15 +1389,16 @@ convertenviron(void)
13901389
d = PyDict_New();
13911390
if (d == NULL)
13921391
return NULL;
1393-
#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1394-
if (environ == NULL)
1395-
environ = *_NSGetEnviron();
1396-
#endif
13971392
#ifdef MS_WINDOWS
13981393
/* _wenviron must be initialized in this way if the program is started
13991394
through main() instead of wmain(). */
14001395
_wgetenv(L"");
14011396
e = _wenviron;
1397+
#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1398+
/* environ is not accessible as an extern in a shared object on OSX; use
1399+
_NSGetEnviron to resolve it. The value changes if you add environment
1400+
variables between calls to Py_Initialize, so don't cache the value. */
1401+
e = *_NSGetEnviron();
14021402
#else
14031403
e = environ;
14041404
#endif

0 commit comments

Comments
 (0)