@@ -50,10 +50,13 @@ using v8::FunctionCallbackInfo;
50
50
using v8::FunctionTemplate;
51
51
using v8::HandleScope;
52
52
using v8::IndexedPropertyHandlerConfiguration;
53
+ using v8::IndexFilter;
53
54
using v8::Int32;
55
+ using v8::Integer;
54
56
using v8::Intercepted;
55
57
using v8::Isolate;
56
58
using v8::Just;
59
+ using v8::KeyCollectionMode;
57
60
using v8::Local;
58
61
using v8::Maybe;
59
62
using v8::MaybeLocal;
@@ -72,6 +75,7 @@ using v8::Promise;
72
75
using v8::PropertyAttribute;
73
76
using v8::PropertyCallbackInfo;
74
77
using v8::PropertyDescriptor;
78
+ using v8::PropertyFilter;
75
79
using v8::PropertyHandlerFlags;
76
80
using v8::Script;
77
81
using v8::ScriptCompiler;
@@ -175,20 +179,22 @@ void ContextifyContext::InitializeGlobalTemplates(IsolateData* isolate_data) {
175
179
NamedPropertyHandlerConfiguration config (
176
180
PropertyGetterCallback,
177
181
PropertySetterCallback,
178
- PropertyDescriptorCallback ,
182
+ PropertyQueryCallback ,
179
183
PropertyDeleterCallback,
180
184
PropertyEnumeratorCallback,
181
185
PropertyDefinerCallback,
186
+ PropertyDescriptorCallback,
182
187
{},
183
188
PropertyHandlerFlags::kHasNoSideEffect );
184
189
185
190
IndexedPropertyHandlerConfiguration indexed_config (
186
191
IndexedPropertyGetterCallback,
187
192
IndexedPropertySetterCallback,
188
- IndexedPropertyDescriptorCallback ,
193
+ IndexedPropertyQueryCallback ,
189
194
IndexedPropertyDeleterCallback,
190
- PropertyEnumeratorCallback ,
195
+ IndexedPropertyEnumeratorCallback ,
191
196
IndexedPropertyDefinerCallback,
197
+ IndexedPropertyDescriptorCallback,
192
198
{},
193
199
PropertyHandlerFlags::kHasNoSideEffect );
194
200
@@ -353,17 +359,20 @@ void ContextifyContext::RegisterExternalReferences(
353
359
ExternalReferenceRegistry* registry) {
354
360
registry->Register (MakeContext);
355
361
registry->Register (CompileFunction);
362
+ registry->Register (PropertyQueryCallback);
356
363
registry->Register (PropertyGetterCallback);
357
364
registry->Register (PropertySetterCallback);
358
365
registry->Register (PropertyDescriptorCallback);
359
366
registry->Register (PropertyDeleterCallback);
360
367
registry->Register (PropertyEnumeratorCallback);
361
368
registry->Register (PropertyDefinerCallback);
369
+ registry->Register (IndexedPropertyQueryCallback);
362
370
registry->Register (IndexedPropertyGetterCallback);
363
371
registry->Register (IndexedPropertySetterCallback);
364
372
registry->Register (IndexedPropertyDescriptorCallback);
365
373
registry->Register (IndexedPropertyDeleterCallback);
366
374
registry->Register (IndexedPropertyDefinerCallback);
375
+ registry->Register (IndexedPropertyEnumeratorCallback);
367
376
}
368
377
369
378
// makeContext(sandbox, name, origin, strings, wasm);
@@ -451,6 +460,51 @@ bool ContextifyContext::IsStillInitializing(const ContextifyContext* ctx) {
451
460
return ctx == nullptr || ctx->context_ .IsEmpty ();
452
461
}
453
462
463
+ // static
464
+ Intercepted ContextifyContext::PropertyQueryCallback (
465
+ Local<Name> property, const PropertyCallbackInfo<Integer>& args) {
466
+ ContextifyContext* ctx = ContextifyContext::Get (args);
467
+
468
+ // Still initializing
469
+ if (IsStillInitializing (ctx)) {
470
+ return Intercepted::kNo ;
471
+ }
472
+
473
+ Local<Context> context = ctx->context ();
474
+ Local<Object> sandbox = ctx->sandbox ();
475
+
476
+ PropertyAttribute attr;
477
+
478
+ Maybe<bool > maybe_has = sandbox->HasRealNamedProperty (context, property);
479
+ if (maybe_has.IsNothing ()) {
480
+ return Intercepted::kNo ;
481
+ } else if (maybe_has.FromJust ()) {
482
+ Maybe<PropertyAttribute> maybe_attr =
483
+ sandbox->GetRealNamedPropertyAttributes (context, property);
484
+ if (!maybe_attr.To (&attr)) {
485
+ return Intercepted::kNo ;
486
+ }
487
+ args.GetReturnValue ().Set (attr);
488
+ return Intercepted::kYes ;
489
+ } else {
490
+ maybe_has = ctx->global_proxy ()->HasRealNamedProperty (context, property);
491
+ if (maybe_has.IsNothing ()) {
492
+ return Intercepted::kNo ;
493
+ } else if (maybe_has.FromJust ()) {
494
+ Maybe<PropertyAttribute> maybe_attr =
495
+ ctx->global_proxy ()->GetRealNamedPropertyAttributes (context,
496
+ property);
497
+ if (!maybe_attr.To (&attr)) {
498
+ return Intercepted::kNo ;
499
+ }
500
+ args.GetReturnValue ().Set (attr);
501
+ return Intercepted::kYes ;
502
+ }
503
+ }
504
+
505
+ return Intercepted::kNo ;
506
+ }
507
+
454
508
// static
455
509
Intercepted ContextifyContext::PropertyGetterCallback (
456
510
Local<Name> property, const PropertyCallbackInfo<Value>& args) {
@@ -695,13 +749,70 @@ void ContextifyContext::PropertyEnumeratorCallback(
695
749
if (IsStillInitializing (ctx)) return ;
696
750
697
751
Local<Array> properties;
698
-
699
- if (!ctx->sandbox ()->GetPropertyNames (ctx->context ()).ToLocal (&properties))
752
+ // Only get named properties, exclude symbols and indices.
753
+ if (!ctx->sandbox ()
754
+ ->GetPropertyNames (
755
+ ctx->context (),
756
+ KeyCollectionMode::kIncludePrototypes ,
757
+ static_cast <PropertyFilter>(PropertyFilter::ONLY_ENUMERABLE |
758
+ PropertyFilter::SKIP_SYMBOLS),
759
+ IndexFilter::kSkipIndices )
760
+ .ToLocal (&properties))
700
761
return ;
701
762
702
763
args.GetReturnValue ().Set (properties);
703
764
}
704
765
766
+ // static
767
+ void ContextifyContext::IndexedPropertyEnumeratorCallback (
768
+ const PropertyCallbackInfo<Array>& args) {
769
+ Isolate* isolate = args.GetIsolate ();
770
+ HandleScope scope (isolate);
771
+ ContextifyContext* ctx = ContextifyContext::Get (args);
772
+ Local<Context> context = ctx->context ();
773
+
774
+ // Still initializing
775
+ if (IsStillInitializing (ctx)) return ;
776
+
777
+ Local<Array> properties;
778
+
779
+ // By default, GetPropertyNames returns string and number property names, and
780
+ // doesn't convert the numbers to strings.
781
+ if (!ctx->sandbox ()->GetPropertyNames (context).ToLocal (&properties)) return ;
782
+
783
+ std::vector<v8::Global<Value>> properties_vec;
784
+ if (FromV8Array (context, properties, &properties_vec).IsNothing ()) {
785
+ return ;
786
+ }
787
+
788
+ // Filter out non-number property names.
789
+ std::vector<Local<Value>> indices;
790
+ for (uint32_t i = 0 ; i < properties->Length (); i++) {
791
+ Local<Value> prop = properties_vec[i].Get (isolate);
792
+ if (!prop->IsNumber ()) {
793
+ continue ;
794
+ }
795
+ indices.push_back (prop);
796
+ }
797
+
798
+ args.GetReturnValue ().Set (
799
+ Array::New (args.GetIsolate (), indices.data (), indices.size ()));
800
+ }
801
+
802
+ // static
803
+ Intercepted ContextifyContext::IndexedPropertyQueryCallback (
804
+ uint32_t index, const PropertyCallbackInfo<Integer>& args) {
805
+ ContextifyContext* ctx = ContextifyContext::Get (args);
806
+
807
+ // Still initializing
808
+ if (IsStillInitializing (ctx)) {
809
+ return Intercepted::kNo ;
810
+ }
811
+
812
+ return ContextifyContext::PropertyQueryCallback (
813
+ Uint32ToName (ctx->context (), index ), args);
814
+ }
815
+
705
816
// static
706
817
Intercepted ContextifyContext::IndexedPropertyGetterCallback (
707
818
uint32_t index, const PropertyCallbackInfo<Value>& args) {
0 commit comments