Skip to content

Commit e2f151f

Browse files
committed
src: make process.env work with symbols in/delete
The getter for process.env already allows symbols to be used, and `in` operator as a read-only operator can do the same. `delete a[b]` operator in ES always returns `true` without doing anything when `b in a === false`. Allow symbols in the deleter accordingly. PR-URL: #11709 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 7a4adb5 commit e2f151f

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

src/node.cc

+23-19
Original file line numberDiff line numberDiff line change
@@ -2787,39 +2787,43 @@ static void EnvSetter(Local<Name> property,
27872787
static void EnvQuery(Local<Name> property,
27882788
const PropertyCallbackInfo<Integer>& info) {
27892789
int32_t rc = -1; // Not found unless proven otherwise.
2790+
if (property->IsString()) {
27902791
#ifdef __POSIX__
2791-
node::Utf8Value key(info.GetIsolate(), property);
2792-
if (getenv(*key))
2793-
rc = 0;
2792+
node::Utf8Value key(info.GetIsolate(), property);
2793+
if (getenv(*key))
2794+
rc = 0;
27942795
#else // _WIN32
2795-
node::TwoByteValue key(info.GetIsolate(), property);
2796-
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2797-
if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
2798-
GetLastError() == ERROR_SUCCESS) {
2799-
rc = 0;
2800-
if (key_ptr[0] == L'=') {
2801-
// Environment variables that start with '=' are hidden and read-only.
2802-
rc = static_cast<int32_t>(v8::ReadOnly) |
2803-
static_cast<int32_t>(v8::DontDelete) |
2804-
static_cast<int32_t>(v8::DontEnum);
2796+
node::TwoByteValue key(info.GetIsolate(), property);
2797+
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2798+
if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
2799+
GetLastError() == ERROR_SUCCESS) {
2800+
rc = 0;
2801+
if (key_ptr[0] == L'=') {
2802+
// Environment variables that start with '=' are hidden and read-only.
2803+
rc = static_cast<int32_t>(v8::ReadOnly) |
2804+
static_cast<int32_t>(v8::DontDelete) |
2805+
static_cast<int32_t>(v8::DontEnum);
2806+
}
28052807
}
2806-
}
28072808
#endif
2809+
}
28082810
if (rc != -1)
28092811
info.GetReturnValue().Set(rc);
28102812
}
28112813

28122814

28132815
static void EnvDeleter(Local<Name> property,
28142816
const PropertyCallbackInfo<Boolean>& info) {
2817+
if (property->IsString()) {
28152818
#ifdef __POSIX__
2816-
node::Utf8Value key(info.GetIsolate(), property);
2817-
unsetenv(*key);
2819+
node::Utf8Value key(info.GetIsolate(), property);
2820+
unsetenv(*key);
28182821
#else
2819-
node::TwoByteValue key(info.GetIsolate(), property);
2820-
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2821-
SetEnvironmentVariableW(key_ptr, nullptr);
2822+
node::TwoByteValue key(info.GetIsolate(), property);
2823+
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2824+
SetEnvironmentVariableW(key_ptr, nullptr);
28222825
#endif
2826+
}
28232827

28242828
// process.env never has non-configurable properties, so always
28252829
// return true like the tc39 delete operator.

test/parallel/test-process-env-symbols.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ assert.throws(() => {
1818
process.env.foo = symbol;
1919
}, errRegExp);
2020

21-
// Verify that using a symbol with the in operator throws.
22-
assert.throws(() => {
23-
symbol in process.env;
24-
}, errRegExp);
21+
// Verify that using a symbol with the in operator returns false.
22+
assert.strictEqual(symbol in process.env, false);
23+
24+
// Verify that deleting a symbol key returns true.
25+
assert.strictEqual(delete process.env[symbol], true);
2526

2627
// Checks that well-known symbols like `Symbol.toStringTag` won’t throw.
2728
assert.doesNotThrow(() => Object.prototype.toString.call(process.env));

0 commit comments

Comments
 (0)