Repository navigation
Unicode characters are not properly parsed from NODE_OPTIONS on Windows #34399
Description
Activity
- addedwindowsIssues and PRs related to the Windows platform.Issues and PRs related to the Windows platform.
on Jul 16, 2020 cc @nodejs/platform-windows
NODE_OPTIONSis parsed bycredentials::SafeGetenv(), which callsgetenv()from libc/msvcrt, and that function may or may not decode multi-byte sequences properly because... well, it's complicated.Switching to
uv_os_getenv()should fix it because that function always performs proper decoding. Untested, but the fix would look like this:Details
diff --git a/src/node_credentials.cc b/src/node_credentials.cc index d552a50172..e77d0378b2 100644 --- a/src/node_credentials.cc +++ b/src/node_credentials.cc @@ -57,9 +57,23 @@ bool SafeGetenv(const char* key, std::string* text, Environment* env) { } { - Mutex::ScopedLock lock(per_process::env_var_mutex); - if (const char* value = getenv(key)) { - *text = value; + MaybeStackBuffer<char, 256> value; + size_t size = 256; // TODO(bnoordhuis) DRY, re-use kStackStorageSize here. + int rc; + + { + Mutex::ScopedLock lock(per_process::env_var_mutex); + rc = uv_os_getenv(key, *value, &size); + } + + if (rc == UV_ENOBUFS) { + value.AllocateSufficientStorage(size); + Mutex::ScopedLock lock(per_process::env_var_mutex); + rc = uv_os_getenv(key, *value, &size); + } + + if (rc >= 0) { + *text = *value; return true; } }
- added 2 commits that reference this issue
on Aug 20, 2020 - added 2 commits that reference this issue
on Aug 20, 2020 I stumbled on this while opening an issue (react/create-react-app#13117) and digging to make sure I understood everything.
I'm just here to say I'm a bit surprised that you use a mutex foruv_os_getenvon all platforms. While the libuv docs sayWarning This function is not thread safe., I do actually suspect the windows implementation is threadsafe!If you compare the windows impl with other OSs, I can see the other impls use classic
getenv, which is obviously unsafe. But the Windows implementation usesGetEnvironmentVariable, which (likegetenv_s) is totally threadsafe. If you read through it, you may be a bit concerned with theSetLastError/GetLastErrorcalls, which is a patch for the kind of thing we've all seen cause issues elsewhere, but that should be thread safe too, since the last error is per-thread (in the TEB, not PEB), not per-process. My windows machine is out of order right now, so I'm relying on ReactOS sources instead of GHIDRA, but it does look like there are locks internally, as I'd expect... so this should be redundant?This probably makes little practical difference. But locks are locks, I bet someone, somewhere, would see a benefit from eliminating it.
What steps will reproduce the bug?
foó.jscontainingconsole.log("in foó");, and anbar.jswithconsole.log("in bar");index.jscontainingindex.jsHow often does it reproduce? Is there a required condition?
Every time
What is the expected behavior?
Output like:
What do you see instead?
Additional information
shell: true/falseinspawn()console.log(process.env.HELLO)in the above example prints out fine\\\\xF3, but it doesn't look like Node tries to parse these from the string.References: microsoft/vscode-js-debug#563