WebKit Bugzilla
Attachment 359953 Details for
Bug 176810
: for..in on a Proxy loops over non enumerable properties
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
(2) [JSC] Filter DontEnum properties in ProxyObject::getOwnPropertyNames()
bug-176810-20190123182532.patch (text/plain), 6.70 KB, created by
Caitlin Potter (:caitp)
on 2019-01-23 15:25:33 PST
(
hide
)
Description:
(2) [JSC] Filter DontEnum properties in ProxyObject::getOwnPropertyNames()
Filename:
MIME Type:
Creator:
Caitlin Potter (:caitp)
Created:
2019-01-23 15:25:33 PST
Size:
6.70 KB
patch
obsolete
>Subversion Revision: 240362 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index a514c8fddd34f5ca4a729fd42814a627e14109a3..0540d42fb1e3ac5f55c928cfaee72cd27ad012b3 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,22 @@ >+2019-01-23 Caitlin Potter <caitp@igalia.com> >+ >+ [JSC] Filter DontEnum properties in ProxyObject::getOwnPropertyNames() >+ https://bugs.webkit.org/show_bug.cgi?id=176810 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This adds conditional logic following the invariant checks, to perform >+ filtering in common uses of getOwnPropertyNames. >+ >+ While this would ideally only be done in JSPropertyNameEnumerator, adding >+ the filtering to ProxyObject::performGetOwnPropertyNames maintains the >+ invariant that the EnumerationMode is properly followed. >+ >+ * runtime/PropertyNameArray.h: >+ (JSC::PropertyNameArray::reset): >+ * runtime/ProxyObject.cpp: >+ (JSC::ProxyObject::performGetOwnPropertyNames): >+ > 2019-01-23 David Kilzer <ddkilzer@apple.com> > > [JSC] Duplicate global variables: JSC::opcodeLengths >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 31aadd832dcae95fcbcbfea27fe4a7c474c2d45b..a09b000a13e685ec51e5bca62ed8323a653115ef 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,21 @@ >+2019-01-23 Caitlin Potter <caitp@igalia.com> >+ >+ [JSC] Filter DontEnum properties in ProxyObject::getOwnPropertyNames() >+ https://bugs.webkit.org/show_bug.cgi?id=176810 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Previously, there was a comment here indicating uncertainty of whether it >+ was necessary to filter DontEnum properties explicitly or not. It turns >+ out that it was necessary in the case of JSC ProxyObjects. >+ >+ This patch adds DontEnum filtering for ProxyObjects, however we continue >+ to explicitly filter them in JSDOMConvertRecord, which needs to use the >+ property descriptor after filtering. This change prevents observably >+ fetching the property descriptor twice per property. >+ >+ * bindings/js/JSDOMConvertRecord.h: >+ > 2019-01-23 Sihui Liu <sihui_liu@apple.com> > > Clean up IndexedDB files between tests >diff --git a/Source/JavaScriptCore/runtime/PropertyNameArray.h b/Source/JavaScriptCore/runtime/PropertyNameArray.h >index 5e93b79abf560234eae8bf4a9e720150e7e14aed..8ec9ac1a70aebf11beaf747e91c77518c46e06e2 100644 >--- a/Source/JavaScriptCore/runtime/PropertyNameArray.h >+++ b/Source/JavaScriptCore/runtime/PropertyNameArray.h >@@ -55,6 +55,12 @@ public: > { > } > >+ void reset() >+ { >+ m_set.clear(); >+ m_data = PropertyNameArrayData::create(); >+ } >+ > VM* vm() { return m_vm; } > > void add(uint32_t index) >diff --git a/Source/JavaScriptCore/runtime/ProxyObject.cpp b/Source/JavaScriptCore/runtime/ProxyObject.cpp >index bbebf3a86ef56a4c34b33655f31828d0b1148f70..38dc87375888224a27e5f66b14544dc356bd5dde 100644 >--- a/Source/JavaScriptCore/runtime/ProxyObject.cpp >+++ b/Source/JavaScriptCore/runtime/ProxyObject.cpp >@@ -993,19 +993,33 @@ void ProxyObject::performGetOwnPropertyNames(ExecState* exec, PropertyNameArray& > } > } > >- if (targetIsExensible) >- return; >+ if (!targetIsExensible) { >+ for (UniquedStringImpl* impl : targetConfigurableKeys) { >+ if (removeIfContainedInUncheckedResultKeys(impl) == IsNotContainedIn) { >+ throwVMTypeError(exec, scope, makeString("Proxy object's non-extensible 'target' has configurable property '", String(impl), "' that was not in the result from the 'ownKeys' trap")); >+ return; >+ } >+ } > >- for (UniquedStringImpl* impl : targetConfigurableKeys) { >- if (removeIfContainedInUncheckedResultKeys(impl) == IsNotContainedIn) { >- throwVMTypeError(exec, scope, makeString("Proxy object's non-extensible 'target' has configurable property '", String(impl), "' that was not in the result from the 'ownKeys' trap")); >+ if (uncheckedResultKeys.size()) { >+ throwVMTypeError(exec, scope, "Proxy handler's 'ownKeys' method returned a key that was not present in its non-extensible target"_s); > return; > } > } > >- if (uncheckedResultKeys.size()) { >- throwVMTypeError(exec, scope, "Proxy handler's 'ownKeys' method returned a key that was not present in its non-extensible target"_s); >- return; >+ if (!enumerationMode.includeDontEnumProperties()) { >+ // Filtering DontEnum properties is observable in proxies and must occur following the invariant checks above. >+ auto data = trapResult.releaseData(); >+ trapResult.reset(); >+ >+ for (auto propertyName : data->propertyNameVector()) { >+ PropertySlot slot(this, PropertySlot::InternalMethodType::GetOwnProperty); >+ if (!getOwnPropertySlotCommon(exec, propertyName, slot)) >+ continue; >+ if (slot.attributes() & PropertyAttribute::DontEnum) >+ continue; >+ trapResult.addUnchecked(propertyName.impl()); >+ } > } > } > >diff --git a/Source/WebCore/bindings/js/JSDOMConvertRecord.h b/Source/WebCore/bindings/js/JSDOMConvertRecord.h >index 75b2eb6aecd2c08db2ac3c4ca63077d119f8f587..df9c3a6ae90cf015bc9697ca2608ce0f8fd1b586 100644 >--- a/Source/WebCore/bindings/js/JSDOMConvertRecord.h >+++ b/Source/WebCore/bindings/js/JSDOMConvertRecord.h >@@ -86,7 +86,7 @@ template<typename K, typename V> struct Converter<IDLRecord<K, V>> : DefaultConv > > // 4. Let keys be ? O.[[OwnPropertyKeys]](). > JSC::PropertyNameArray keys(&vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude); >- object->methodTable(vm)->getOwnPropertyNames(object, &state, keys, JSC::EnumerationMode()); >+ object->methodTable(vm)->getOwnPropertyNames(object, &state, keys, JSC::EnumerationMode(JSC::DontEnumPropertiesMode::Include)); > > RETURN_IF_EXCEPTION(scope, { }); > >@@ -99,9 +99,8 @@ template<typename K, typename V> struct Converter<IDLRecord<K, V>> : DefaultConv > > // 2. If desc is not undefined and desc.[[Enumerable]] is true: > >- // FIXME: Do we need to check for enumerable / undefined, or is this handled by the default >- // enumeration mode? >- >+ // It's necessary to filter enumerable here rather than using the default EnumerationMode, >+ // to prevent an observable extra [[GetOwnProperty]] operation in the case of ProxyObject records. > if (didGetDescriptor && descriptor.enumerable()) { > // 1. Let typedKey be key converted to an IDL value of type K. > auto typedKey = Detail::IdentifierConverter<K>::convert(state, key);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 176810
:
351389
|
351402
|
351405
|
351412
|
351468
|
351472
|
359910
|
359911
|
359912
|
359922
|
359930
|
359935
|
359937
|
359941
|
359952
|
359953
|
359955
|
359959
|
359961
|
359975
|
359979
|
359980
|
359988
|
360004
|
360032
|
362731
|
362762
|
362812
|
362896
|
366956
|
367326