Skip to content

Commit 6acb1a3

Browse files
addaleaxjasnell
authored andcommitted
process: fix reading zero-length env vars on win32
Up until now, Node did not clear the current error code attempting to read environment variables on Windows. Since checking the error code is the way we distinguish between missing and zero-length environment variables, this could lead to a false positive when the error code was still tainted. In the simplest case, accessing a missing variable and then a zero-length one would lead Node to believe that both calls yielded an error. Before: > process.env.I=''; process.env.Q; process.env.I undefined > process.env.I=''; /*process.env.Q;*/ process.env.I '' After: > process.env.I=''; process.env.Q; process.env.I '' > process.env.I=''; /*process.env.Q;*/ process.env.I '' This only affects Node 8 and above, since before 1aa595e we always constructed a `v8::String::Value` instance for passing the lookup key to the OS, which in in turn always made a heap allocation and therefore reset the error code. PR-URL: #18463 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent 6e7992e commit 6acb1a3

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

src/node.cc

+2
Original file line numberDiff line numberDiff line change
@@ -2603,6 +2603,7 @@ static void EnvGetter(Local<Name> property,
26032603
#else // _WIN32
26042604
node::TwoByteValue key(isolate, property);
26052605
WCHAR buffer[32767]; // The maximum size allowed for environment variables.
2606+
SetLastError(ERROR_SUCCESS);
26062607
DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
26072608
buffer,
26082609
arraysize(buffer));
@@ -2651,6 +2652,7 @@ static void EnvQuery(Local<Name> property,
26512652
#else // _WIN32
26522653
node::TwoByteValue key(info.GetIsolate(), property);
26532654
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2655+
SetLastError(ERROR_SUCCESS);
26542656
if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
26552657
GetLastError() == ERROR_SUCCESS) {
26562658
rc = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
5+
// This checks that after accessing a missing env var, a subsequent
6+
// env read will succeed even for empty variables.
7+
8+
{
9+
process.env.FOO = '';
10+
process.env.NONEXISTENT_ENV_VAR;
11+
const foo = process.env.FOO;
12+
13+
assert.strictEqual(foo, '');
14+
}
15+
16+
{
17+
process.env.FOO = '';
18+
process.env.NONEXISTENT_ENV_VAR;
19+
const hasFoo = 'FOO' in process.env;
20+
21+
assert.strictEqual(hasFoo, true);
22+
}

0 commit comments

Comments
 (0)