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:
Timothy Gu 2017-03-05 22:45:19 -08:00
parent 7a4adb5b60
commit e2f151f5b2
2 changed files with 28 additions and 23 deletions

View File

@ -2787,6 +2787,7 @@ 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))
@ -2805,6 +2806,7 @@ static void EnvQuery(Local<Name> property,
}
}
#endif
}
if (rc != -1)
info.GetReturnValue().Set(rc);
}
@ -2812,6 +2814,7 @@ 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);
@ -2820,6 +2823,7 @@ static void EnvDeleter(Local<Name> 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.

View File

@ -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` wont throw.
assert.doesNotThrow(() => Object.prototype.toString.call(process.env));