diff --git a/src/node_env_var.cc b/src/node_env_var.cc index 5f7ef8cc58f589..0c3376d9a5f8d9 100644 --- a/src/node_env_var.cc +++ b/src/node_env_var.cc @@ -4,6 +4,7 @@ #include "node_external_reference.h" #include "node_i18n.h" #include "node_process-inl.h" +#include "util.h" #include // tzset(), _tzset() #include @@ -16,6 +17,7 @@ using v8::DontDelete; using v8::DontEnum; using v8::FunctionTemplate; using v8::HandleScope; +using v8::IndexedPropertyHandlerConfiguration; using v8::Integer; using v8::Intercepted; using v8::Isolate; @@ -570,6 +572,43 @@ static Intercepted EnvDefiner(Local property, } } +static Intercepted EnvGetterIndexed(uint32_t index, + const PropertyCallbackInfo& info) { + Environment* env = Environment::GetCurrent(info); + Local name = Uint32ToString(env->context(), index); + return EnvGetter(name, info); +} + +static Intercepted EnvSetterIndexed(uint32_t index, + Local value, + const PropertyCallbackInfo& info) { + Environment* env = Environment::GetCurrent(info); + Local name = Uint32ToString(env->context(), index); + return EnvSetter(name, value, info); +} + +static Intercepted EnvQueryIndexed(uint32_t index, + const PropertyCallbackInfo& info) { + Environment* env = Environment::GetCurrent(info); + Local name = Uint32ToString(env->context(), index); + return EnvQuery(name, info); +} + +static Intercepted EnvDeleterIndexed( + uint32_t index, const PropertyCallbackInfo& info) { + Environment* env = Environment::GetCurrent(info); + Local name = Uint32ToString(env->context(), index); + return EnvDeleter(name, info); +} + +static Intercepted EnvDefinerIndexed(uint32_t index, + const PropertyDescriptor& desc, + const PropertyCallbackInfo& info) { + Environment* env = Environment::GetCurrent(info); + Local name = Uint32ToString(env->context(), index); + return EnvDefiner(name, desc, info); +} + void CreateEnvProxyTemplate(IsolateData* isolate_data) { Isolate* isolate = isolate_data->isolate(); HandleScope scope(isolate); @@ -588,6 +627,16 @@ void CreateEnvProxyTemplate(IsolateData* isolate_data) { nullptr, Local(), PropertyHandlerFlags::kHasNoSideEffect)); + env_proxy_template->SetHandler(IndexedPropertyHandlerConfiguration( + EnvGetterIndexed, + EnvSetterIndexed, + EnvQueryIndexed, + EnvDeleterIndexed, + nullptr, + EnvDefinerIndexed, + nullptr, + Local(), + PropertyHandlerFlags::kHasNoSideEffect)); isolate_data->set_env_proxy_template(env_proxy_template); isolate_data->set_env_proxy_ctor_template(env_proxy_ctor_template); } @@ -599,6 +648,11 @@ void RegisterEnvVarExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(EnvDeleter); registry->Register(EnvEnumerator); registry->Register(EnvDefiner); + registry->Register(EnvGetterIndexed); + registry->Register(EnvSetterIndexed); + registry->Register(EnvQueryIndexed); + registry->Register(EnvDeleterIndexed); + registry->Register(EnvDefinerIndexed); } } // namespace node diff --git a/test/parallel/test-process-env.js b/test/parallel/test-process-env.js index f20be5a194dbf9..bd2cd066fa2285 100644 --- a/test/parallel/test-process-env.js +++ b/test/parallel/test-process-env.js @@ -29,6 +29,7 @@ if (process.argv[2] === 'you-are-the-child') { assert.strictEqual('NODE_PROCESS_ENV_DELETED' in process.env, false); assert.strictEqual(process.env.NODE_PROCESS_ENV, '42'); assert.strictEqual(process.env.hasOwnProperty, 'asdf'); + assert.strictEqual(process.env[42], 'forty-two'); const has = Object.hasOwn(process.env, 'hasOwnProperty'); assert.strictEqual(has, true); process.exit(0); @@ -47,6 +48,9 @@ if (process.argv[2] === 'you-are-the-child') { process.env.NODE_PROCESS_ENV = 42; assert.strictEqual(process.env.NODE_PROCESS_ENV, '42'); + process.env[42] = 'forty-two'; + assert.strictEqual(process.env[42], 'forty-two'); + process.env.NODE_PROCESS_ENV_DELETED = 42; assert.strictEqual('NODE_PROCESS_ENV_DELETED' in process.env, true);