This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Windows: convertenviron() doesn't parse environment variables properly
Type: Stage: resolved
Components: Library (Lib) Versions: Python 3.9
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: eryksun, vstinner
Priority: normal Keywords:

Created on 2020-01-22 15:10 by vstinner, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg360473 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-01-22 15:10
os.environ is created by convertenviron() of posixmodule.c. The Windows implementation calls _wgetenv(L"") to initialize _wenviron, and then parses the _wenviron string.

The _wenviron string is parsed by search for the first "=" character to split between the variable name and the variable value. For example, "USER=vstinner" is parsed as name="USER" and value="vstinner".

The problem is that the _wputenv() function allows to insert variable names containing the "=" character (but reject names starting with "=" character). Python can inherit an environment with a name containing "=".

One solution can be to use GetEnvironmentStringsW() which uses null characters to separate variable name and variable value. It returns a string like "name1\0value1\0name2\0value2\0\0": the string ends with a null character as well, to mark the end of the list.

https://docs.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-getenvironmentstrings?redirectedfrom=MSDN

Python 3.8 *explicitly* rejects variable names containing "=", at least on Windows, likely to workaround this issue. But another program can inject such variable in the environment.

Example with a Python modified to not reject explicitly "=" in the varaible name:
---
import subprocess, os, sys
os.putenv("victor=", "secret")
code = """import os; print(f"victor: {os.getenv('victor')!r}"); print(f"victor=: {os.getenv('victor=')!r}")"""
subprocess.run([sys.executable, "-c", code])
---

Output:
---
victor: '=secret'
victor=: None
---

Expected output:
---
victor: None
victor=: '=secret'
---
msg360490 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2020-01-22 17:28
> The problem is that the _wputenv() function allows to insert variable 
> names containing the "=" character 

No, it does not. Your experiments uncovered bugs elsewhere with the implementations of _wgetenv and WINAPI GetEnvironmentVariableW, but this isn't one of them. _wputenv(L"victor==secret") updates the OS environment by calling SetEnvironmentVariableW(L"victor", L"=secret"). That is the only correct result. A variable name is only allowed to contain "=" as the first character, where it is unambiguous. The first "=" beyond the first character must be the value delimiter.
msg360597 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-01-24 08:57
You're right, Windows works as expected. I close the issue.

See https://github.com/python/cpython/pull/18115 for more information.
History
Date User Action Args
2022-04-11 14:59:25adminsetgithub: 83601
2020-01-24 08:57:53vstinnersetstatus: open -> closed
resolution: not a bug
messages: + msg360597

stage: resolved
2020-01-22 17:28:39eryksunsetnosy: + eryksun
messages: + msg360490
2020-01-22 15:10:19vstinnercreate