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: https://github.com/nodejs/node/pull/11709 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
7a4adb5b60
commit
e2f151f5b2
42
src/node.cc
42
src/node.cc
@ -2787,24 +2787,26 @@ static void EnvSetter(Local<Name> property,
|
||||
static void EnvQuery(Local<Name> property,
|
||||
const PropertyCallbackInfo<Integer>& info) {
|
||||
int32_t rc = -1; // Not found unless proven otherwise.
|
||||
if (property->IsString()) {
|
||||
#ifdef __POSIX__
|
||||
node::Utf8Value key(info.GetIsolate(), property);
|
||||
if (getenv(*key))
|
||||
rc = 0;
|
||||
node::Utf8Value key(info.GetIsolate(), property);
|
||||
if (getenv(*key))
|
||||
rc = 0;
|
||||
#else // _WIN32
|
||||
node::TwoByteValue key(info.GetIsolate(), property);
|
||||
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
|
||||
if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
|
||||
GetLastError() == ERROR_SUCCESS) {
|
||||
rc = 0;
|
||||
if (key_ptr[0] == L'=') {
|
||||
// Environment variables that start with '=' are hidden and read-only.
|
||||
rc = static_cast<int32_t>(v8::ReadOnly) |
|
||||
static_cast<int32_t>(v8::DontDelete) |
|
||||
static_cast<int32_t>(v8::DontEnum);
|
||||
node::TwoByteValue key(info.GetIsolate(), property);
|
||||
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
|
||||
if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
|
||||
GetLastError() == ERROR_SUCCESS) {
|
||||
rc = 0;
|
||||
if (key_ptr[0] == L'=') {
|
||||
// Environment variables that start with '=' are hidden and read-only.
|
||||
rc = static_cast<int32_t>(v8::ReadOnly) |
|
||||
static_cast<int32_t>(v8::DontDelete) |
|
||||
static_cast<int32_t>(v8::DontEnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (rc != -1)
|
||||
info.GetReturnValue().Set(rc);
|
||||
}
|
||||
@ -2812,14 +2814,16 @@ static void EnvQuery(Local<Name> property,
|
||||
|
||||
static void EnvDeleter(Local<Name> property,
|
||||
const PropertyCallbackInfo<Boolean>& info) {
|
||||
if (property->IsString()) {
|
||||
#ifdef __POSIX__
|
||||
node::Utf8Value key(info.GetIsolate(), property);
|
||||
unsetenv(*key);
|
||||
node::Utf8Value key(info.GetIsolate(), property);
|
||||
unsetenv(*key);
|
||||
#else
|
||||
node::TwoByteValue key(info.GetIsolate(), property);
|
||||
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
|
||||
SetEnvironmentVariableW(key_ptr, nullptr);
|
||||
node::TwoByteValue key(info.GetIsolate(), property);
|
||||
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
|
||||
SetEnvironmentVariableW(key_ptr, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
// process.env never has non-configurable properties, so always
|
||||
// return true like the tc39 delete operator.
|
||||
|
@ -18,10 +18,11 @@ assert.throws(() => {
|
||||
process.env.foo = symbol;
|
||||
}, errRegExp);
|
||||
|
||||
// Verify that using a symbol with the in operator throws.
|
||||
assert.throws(() => {
|
||||
symbol in process.env;
|
||||
}, errRegExp);
|
||||
// Verify that using a symbol with the in operator returns false.
|
||||
assert.strictEqual(symbol in process.env, false);
|
||||
|
||||
// Verify that deleting a symbol key returns true.
|
||||
assert.strictEqual(delete process.env[symbol], true);
|
||||
|
||||
// Checks that well-known symbols like `Symbol.toStringTag` won’t throw.
|
||||
assert.doesNotThrow(() => Object.prototype.toString.call(process.env));
|
||||
|
Loading…
x
Reference in New Issue
Block a user