Skip to content

Commit 9cda07b

Browse files
committed
src: handled indexed properties in process.env
Closes: #60795
1 parent 189a0a7 commit 9cda07b

File tree

5 files changed

+88
-25
lines changed

5 files changed

+88
-25
lines changed

src/node_contextify.cc

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ using v8::ScriptCompiler;
8585
using v8::ScriptOrigin;
8686
using v8::String;
8787
using v8::Symbol;
88-
using v8::Uint32;
8988
using v8::UnboundScript;
9089
using v8::Value;
9190

@@ -109,15 +108,6 @@ using v8::Value;
109108
// For every `set` of a global property, the interceptor callback defines or
110109
// changes the property both on the sandbox and the global proxy.
111110

112-
namespace {
113-
114-
// Convert an int to a V8 Name (String or Symbol).
115-
MaybeLocal<String> Uint32ToName(Local<Context> context, uint32_t index) {
116-
return Uint32::New(Isolate::GetCurrent(), index)->ToString(context);
117-
}
118-
119-
} // anonymous namespace
120-
121111
ContextifyContext* ContextifyContext::New(Environment* env,
122112
Local<Object> sandbox_obj,
123113
ContextOptions* options) {
@@ -850,7 +840,7 @@ Intercepted ContextifyContext::IndexedPropertyQueryCallback(
850840
}
851841

852842
Local<String> name;
853-
if (Uint32ToName(ctx->context(), index).ToLocal(&name)) {
843+
if (Uint32ToString(ctx->context(), index).ToLocal(&name)) {
854844
return ContextifyContext::PropertyQueryCallback(name, args);
855845
}
856846
return Intercepted::kNo;
@@ -867,7 +857,7 @@ Intercepted ContextifyContext::IndexedPropertyGetterCallback(
867857
}
868858

869859
Local<String> name;
870-
if (Uint32ToName(ctx->context(), index).ToLocal(&name)) {
860+
if (Uint32ToString(ctx->context(), index).ToLocal(&name)) {
871861
return ContextifyContext::PropertyGetterCallback(name, args);
872862
}
873863
return Intercepted::kNo;
@@ -885,7 +875,7 @@ Intercepted ContextifyContext::IndexedPropertySetterCallback(
885875
}
886876

887877
Local<String> name;
888-
if (Uint32ToName(ctx->context(), index).ToLocal(&name)) {
878+
if (Uint32ToString(ctx->context(), index).ToLocal(&name)) {
889879
return ContextifyContext::PropertySetterCallback(name, value, args);
890880
}
891881
return Intercepted::kNo;
@@ -902,7 +892,7 @@ Intercepted ContextifyContext::IndexedPropertyDescriptorCallback(
902892
}
903893

904894
Local<String> name;
905-
if (Uint32ToName(ctx->context(), index).ToLocal(&name)) {
895+
if (Uint32ToString(ctx->context(), index).ToLocal(&name)) {
906896
return ContextifyContext::PropertyDescriptorCallback(name, args);
907897
}
908898
return Intercepted::kNo;
@@ -920,7 +910,7 @@ Intercepted ContextifyContext::IndexedPropertyDefinerCallback(
920910
}
921911

922912
Local<String> name;
923-
if (Uint32ToName(ctx->context(), index).ToLocal(&name)) {
913+
if (Uint32ToString(ctx->context(), index).ToLocal(&name)) {
924914
return ContextifyContext::PropertyDefinerCallback(name, desc, args);
925915
}
926916
return Intercepted::kNo;

src/node_env_var.cc

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "node_external_reference.h"
55
#include "node_i18n.h"
66
#include "node_process-inl.h"
7+
#include "util.h"
78

89
#include <time.h> // tzset(), _tzset()
910
#include <optional>
@@ -16,6 +17,7 @@ using v8::DontDelete;
1617
using v8::DontEnum;
1718
using v8::FunctionTemplate;
1819
using v8::HandleScope;
20+
using v8::IndexedPropertyHandlerConfiguration;
1921
using v8::Integer;
2022
using v8::Intercepted;
2123
using v8::Isolate;
@@ -570,6 +572,58 @@ static Intercepted EnvDefiner(Local<Name> property,
570572
}
571573
}
572574

575+
static Intercepted EnvGetterIndexed(uint32_t index,
576+
const PropertyCallbackInfo<Value>& info) {
577+
Environment* env = Environment::GetCurrent(info);
578+
Local<Name> name;
579+
if (!Uint32ToString(env->context(), index).ToLocal(&name)) {
580+
return Intercepted::kYes;
581+
}
582+
return EnvGetter(name, info);
583+
}
584+
585+
static Intercepted EnvSetterIndexed(uint32_t index,
586+
Local<Value> value,
587+
const PropertyCallbackInfo<void>& info) {
588+
Environment* env = Environment::GetCurrent(info);
589+
Local<Name> name;
590+
if (!Uint32ToString(env->context(), index).ToLocal(&name)) {
591+
return Intercepted::kYes;
592+
}
593+
return EnvSetter(name, value, info);
594+
}
595+
596+
static Intercepted EnvQueryIndexed(uint32_t index,
597+
const PropertyCallbackInfo<Integer>& info) {
598+
Environment* env = Environment::GetCurrent(info);
599+
Local<Name> name;
600+
if (!Uint32ToString(env->context(), index).ToLocal(&name)) {
601+
return Intercepted::kYes;
602+
}
603+
return EnvQuery(name, info);
604+
}
605+
606+
static Intercepted EnvDeleterIndexed(
607+
uint32_t index, const PropertyCallbackInfo<Boolean>& info) {
608+
Environment* env = Environment::GetCurrent(info);
609+
Local<Name> name;
610+
if (!Uint32ToString(env->context(), index).ToLocal(&name)) {
611+
return Intercepted::kYes;
612+
}
613+
return EnvDeleter(name, info);
614+
}
615+
616+
static Intercepted EnvDefinerIndexed(uint32_t index,
617+
const PropertyDescriptor& desc,
618+
const PropertyCallbackInfo<void>& info) {
619+
Environment* env = Environment::GetCurrent(info);
620+
Local<Name> name;
621+
if (!Uint32ToString(env->context(), index).ToLocal(&name)) {
622+
return Intercepted::kYes;
623+
}
624+
return EnvDefiner(name, desc, info);
625+
}
626+
573627
void CreateEnvProxyTemplate(IsolateData* isolate_data) {
574628
Isolate* isolate = isolate_data->isolate();
575629
HandleScope scope(isolate);
@@ -588,6 +642,16 @@ void CreateEnvProxyTemplate(IsolateData* isolate_data) {
588642
nullptr,
589643
Local<Value>(),
590644
PropertyHandlerFlags::kHasNoSideEffect));
645+
env_proxy_template->SetHandler(IndexedPropertyHandlerConfiguration(
646+
EnvGetterIndexed,
647+
EnvSetterIndexed,
648+
EnvQueryIndexed,
649+
EnvDeleterIndexed,
650+
nullptr,
651+
EnvDefinerIndexed,
652+
nullptr,
653+
Local<Value>(),
654+
PropertyHandlerFlags::kHasNoSideEffect));
591655
isolate_data->set_env_proxy_template(env_proxy_template);
592656
isolate_data->set_env_proxy_ctor_template(env_proxy_ctor_template);
593657
}
@@ -599,6 +663,11 @@ void RegisterEnvVarExternalReferences(ExternalReferenceRegistry* registry) {
599663
registry->Register(EnvDeleter);
600664
registry->Register(EnvEnumerator);
601665
registry->Register(EnvDefiner);
666+
registry->Register(EnvGetterIndexed);
667+
registry->Register(EnvSetterIndexed);
668+
registry->Register(EnvQueryIndexed);
669+
registry->Register(EnvDeleterIndexed);
670+
registry->Register(EnvDefinerIndexed);
602671
}
603672
} // namespace node
604673

src/node_webstorage.cc

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ using v8::PropertyCallbackInfo;
4141
using v8::PropertyDescriptor;
4242
using v8::PropertyHandlerFlags;
4343
using v8::String;
44-
using v8::Uint32;
4544
using v8::Value;
4645

4746
#define THROW_SQLITE_ERROR(env, r) \
@@ -432,10 +431,6 @@ Maybe<void> Storage::Store(Local<Name> key, Local<Value> value) {
432431
return JustVoid();
433432
}
434433

435-
static MaybeLocal<String> Uint32ToName(Local<Context> context, uint32_t index) {
436-
return Uint32::New(Isolate::GetCurrent(), index)->ToString(context);
437-
}
438-
439434
static void Clear(const FunctionCallbackInfo<Value>& info) {
440435
Storage* storage;
441436
ASSIGN_OR_RETURN_UNWRAP(&storage, info.This());
@@ -632,7 +627,7 @@ static Intercepted IndexedGetter(uint32_t index,
632627
const PropertyCallbackInfo<Value>& info) {
633628
Environment* env = Environment::GetCurrent(info);
634629
Local<Name> name;
635-
if (!Uint32ToName(env->context(), index).ToLocal(&name)) {
630+
if (!Uint32ToString(env->context(), index).ToLocal(&name)) {
636631
// There was an error converting the index to a name.
637632
// We aren't going to return a result but let's indicate
638633
// that we intercepted the operation.
@@ -646,7 +641,7 @@ static Intercepted IndexedSetter(uint32_t index,
646641
const PropertyCallbackInfo<void>& info) {
647642
Environment* env = Environment::GetCurrent(info);
648643
Local<Name> name;
649-
if (!Uint32ToName(env->context(), index).ToLocal(&name)) {
644+
if (!Uint32ToString(env->context(), index).ToLocal(&name)) {
650645
// There was an error converting the index to a name.
651646
// We aren't going to return a result but let's indicate
652647
// that we intercepted the operation.
@@ -659,7 +654,7 @@ static Intercepted IndexedQuery(uint32_t index,
659654
const PropertyCallbackInfo<Integer>& info) {
660655
Environment* env = Environment::GetCurrent(info);
661656
Local<Name> name;
662-
if (!Uint32ToName(env->context(), index).ToLocal(&name)) {
657+
if (!Uint32ToString(env->context(), index).ToLocal(&name)) {
663658
// There was an error converting the index to a name.
664659
// We aren't going to return a result but let's indicate
665660
// that we intercepted the operation.
@@ -672,7 +667,7 @@ static Intercepted IndexedDeleter(uint32_t index,
672667
const PropertyCallbackInfo<Boolean>& info) {
673668
Environment* env = Environment::GetCurrent(info);
674669
Local<Name> name;
675-
if (!Uint32ToName(env->context(), index).ToLocal(&name)) {
670+
if (!Uint32ToString(env->context(), index).ToLocal(&name)) {
676671
// There was an error converting the index to a name.
677672
// We aren't going to return a result but let's indicate
678673
// that we intercepted the operation.
@@ -686,7 +681,7 @@ static Intercepted IndexedDefiner(uint32_t index,
686681
const PropertyCallbackInfo<void>& info) {
687682
Environment* env = Environment::GetCurrent(info);
688683
Local<Name> name;
689-
if (!Uint32ToName(env->context(), index).ToLocal(&name)) {
684+
if (!Uint32ToString(env->context(), index).ToLocal(&name)) {
690685
// There was an error converting the index to a name.
691686
// We aren't going to return a result but let's indicate
692687
// that we intercepted the operation.

src/util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,11 @@ inline v8::Local<v8::String> FIXED_ONE_BYTE_STRING(v8::Isolate* isolate,
364364
return OneByteString(isolate, data, N - 1, v8::NewStringType::kInternalized);
365365
}
366366

367+
inline v8::MaybeLocal<v8::String> Uint32ToString(v8::Local<v8::Context> context,
368+
uint32_t value) {
369+
return v8::Uint32::New(v8::Isolate::GetCurrent(), value)->ToString(context);
370+
}
371+
367372
// tolower() is locale-sensitive. Use ToLower() instead.
368373
inline char ToLower(char c);
369374
template <typename T>

test/parallel/test-process-env.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ if (process.argv[2] === 'you-are-the-child') {
2929
assert.strictEqual('NODE_PROCESS_ENV_DELETED' in process.env, false);
3030
assert.strictEqual(process.env.NODE_PROCESS_ENV, '42');
3131
assert.strictEqual(process.env.hasOwnProperty, 'asdf');
32+
assert.strictEqual(process.env[42], 'forty-two');
3233
const has = Object.hasOwn(process.env, 'hasOwnProperty');
3334
assert.strictEqual(has, true);
3435
process.exit(0);
@@ -47,6 +48,9 @@ if (process.argv[2] === 'you-are-the-child') {
4748
process.env.NODE_PROCESS_ENV = 42;
4849
assert.strictEqual(process.env.NODE_PROCESS_ENV, '42');
4950

51+
process.env[42] = 'forty-two';
52+
assert.strictEqual(process.env[42], 'forty-two');
53+
5054
process.env.NODE_PROCESS_ENV_DELETED = 42;
5155
assert.strictEqual('NODE_PROCESS_ENV_DELETED' in process.env, true);
5256

0 commit comments

Comments
 (0)