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, static void EnvQuery(Local<Name> property,
const PropertyCallbackInfo<Integer>& info) { const PropertyCallbackInfo<Integer>& info) {
int32_t rc = -1; // Not found unless proven otherwise. int32_t rc = -1; // Not found unless proven otherwise.
if (property->IsString()) {
#ifdef __POSIX__ #ifdef __POSIX__
node::Utf8Value key(info.GetIsolate(), property); node::Utf8Value key(info.GetIsolate(), property);
if (getenv(*key)) if (getenv(*key))
@ -2805,6 +2806,7 @@ static void EnvQuery(Local<Name> property,
} }
} }
#endif #endif
}
if (rc != -1) if (rc != -1)
info.GetReturnValue().Set(rc); info.GetReturnValue().Set(rc);
} }
@ -2812,6 +2814,7 @@ static void EnvQuery(Local<Name> property,
static void EnvDeleter(Local<Name> property, static void EnvDeleter(Local<Name> property,
const PropertyCallbackInfo<Boolean>& info) { const PropertyCallbackInfo<Boolean>& info) {
if (property->IsString()) {
#ifdef __POSIX__ #ifdef __POSIX__
node::Utf8Value key(info.GetIsolate(), property); node::Utf8Value key(info.GetIsolate(), property);
unsetenv(*key); unsetenv(*key);
@ -2820,6 +2823,7 @@ static void EnvDeleter(Local<Name> property,
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key); WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
SetEnvironmentVariableW(key_ptr, nullptr); SetEnvironmentVariableW(key_ptr, nullptr);
#endif #endif
}
// process.env never has non-configurable properties, so always // process.env never has non-configurable properties, so always
// return true like the tc39 delete operator. // return true like the tc39 delete operator.

View File

@ -18,10 +18,11 @@ assert.throws(() => {
process.env.foo = symbol; process.env.foo = symbol;
}, errRegExp); }, errRegExp);
// Verify that using a symbol with the in operator throws. // Verify that using a symbol with the in operator returns false.
assert.throws(() => { assert.strictEqual(symbol in process.env, false);
symbol in process.env;
}, errRegExp); // 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. // Checks that well-known symbols like `Symbol.toStringTag` wont throw.
assert.doesNotThrow(() => Object.prototype.toString.call(process.env)); assert.doesNotThrow(() => Object.prototype.toString.call(process.env));