[JSC] REGRESSION(r135093): A form control with name=length overrides length property...
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Jan 2013 03:55:33 +0000 (03:55 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Jan 2013 03:55:33 +0000 (03:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=105775

Reviewed by Sam Weinig.

Source/WebCore:

Fixed the bug by respecting properties on ancestor classes.

Test: fast/dom/collection-length-should-not-be-overridden.html

* bindings/js/JSDOMBinding.h:
(WebCore::getStaticValueSlotEntryWithoutCaching): Added.
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateGetOwnPropertySlotBody): Use getStaticValueSlotEntryWithoutCaching to climb up the class
hierarchy.

LayoutTests:

Added a regression tests for all known HTMLCollection sublcasses except HTMLNameCollection,
which is used only to implement named getters on window and document objects and HTMLPropertiesCollection
since it's not enabled on all ports yet.

* fast/dom/collection-length-should-not-be-overridden-expected.txt: Added.
* fast/dom/collection-length-should-not-be-overridden.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@139278 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/dom/collection-length-should-not-be-overridden-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/collection-length-should-not-be-overridden.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMBinding.h
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

index 29eee0842c017d193e6e57b2facdc1b328aad577..8bbfc34536721965a1623c0f4a941b3e8ba6379b 100644 (file)
@@ -1,3 +1,17 @@
+2013-01-09  Ryosuke Niwa  <rniwa@webkit.org>
+
+        [JSC] REGRESSION(r135093): A form control with name=length overrides length property on form.elements
+        https://bugs.webkit.org/show_bug.cgi?id=105775
+
+        Reviewed by Sam Weinig.
+
+        Added a regression tests for all known HTMLCollection sublcasses except HTMLNameCollection,
+        which is used only to implement named getters on window and document objects and HTMLPropertiesCollection
+        since it's not enabled on all ports yet.
+
+        * fast/dom/collection-length-should-not-be-overridden-expected.txt: Added.
+        * fast/dom/collection-length-should-not-be-overridden.html: Added.
+
 2013-01-09  Shinya Kawanaka  <shinyak@chromium.org>
 
         Assert triggered in SelectorChecker::checkOneSelector when scrollbar (e.g. :horizontal) selector is specified.
diff --git a/LayoutTests/fast/dom/collection-length-should-not-be-overridden-expected.txt b/LayoutTests/fast/dom/collection-length-should-not-be-overridden-expected.txt
new file mode 100644 (file)
index 0000000..9cf751c
--- /dev/null
@@ -0,0 +1,22 @@
+This test ensures the builtin length property of HTMLCollection's subclasses is not overridden by a named getter of the same name.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS documentAllLength is 18
+PASS documentAll5 is documentAllSome
+PASS documentAll6.name is 'length'
+PASS form.length is form.elements[1]
+PASS form.elements.length is 2
+PASS form.elements[0] is form.elements['some']
+PASS form.elements[1].name is 'length'
+PASS select.options.length is 2
+PASS select.options[0].getAttribute('name') is 'length'
+PASS select.options[1] is select.options['some']
+PASS table.rows.length is 2
+PASS table.rows[0] is table.rows['another']
+PASS table.rows[1].id is 'length'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/collection-length-should-not-be-overridden.html b/LayoutTests/fast/dom/collection-length-should-not-be-overridden.html
new file mode 100644 (file)
index 0000000..bd209fd
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div id="testElements">
+<form>
+<input type="text" name="some">
+<input type="text" name="length">
+</form>
+<form>
+<select>
+<option name="length">
+<option name="some">
+</select>
+</form>
+<table>
+<tbody>
+<tr id="another"><td></td></tr>
+<tr id="length"><td></td></tr>
+</tbody>
+</table>
+</div>
+<script>
+
+// We need to pre-fetch these values since including the script element inserts new elements.
+documentAllLength = document.all.length;
+documentAllSome = document.all['some'];
+documentAll5 = document.all[5];
+documentAll6 = document.all[6];
+
+</script>
+<script src="../js/resources/js-test-pre.js"></script>
+<script>
+
+description("This test ensures the builtin length property of HTMLCollection's subclasses is not overridden by a named getter of the same name.");
+
+var form = document.forms[0];
+var select = document.querySelector('select');
+var table = document.querySelector('table');
+shouldBe("documentAllLength", "18");
+shouldBe("documentAll5", "documentAllSome");
+shouldBe("documentAll6.name", "'length'");
+
+shouldBe("form.length", "form.elements[1]");
+shouldBe("form.elements.length", "2");
+shouldBe("form.elements[0]", "form.elements['some']");
+shouldBe("form.elements[1].name", "'length'");
+
+shouldBe("select.options.length", "2");
+shouldBe("select.options[0].getAttribute('name')", "'length'");
+shouldBe("select.options[1]", "select.options['some']");
+
+shouldBe("table.rows.length", "2");
+shouldBe("table.rows[0]", "table.rows['another']");
+shouldBe("table.rows[1].id", "'length'");
+
+document.getElementById('testElements').style.display = 'none';
+
+var successfullyParsed = true;
+
+</script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
index 348318645dd6b9fe5af9c6f6f9ce4fe5170bc59a..6833188946febcb47fd9d446b6eb22d6d8a493ad 100644 (file)
@@ -1,3 +1,20 @@
+2013-01-09  Ryosuke Niwa  <rniwa@webkit.org>
+
+        [JSC] REGRESSION(r135093): A form control with name=length overrides length property on form.elements
+        https://bugs.webkit.org/show_bug.cgi?id=105775
+
+        Reviewed by Sam Weinig.
+
+        Fixed the bug by respecting properties on ancestor classes.
+
+        Test: fast/dom/collection-length-should-not-be-overridden.html
+
+        * bindings/js/JSDOMBinding.h:
+        (WebCore::getStaticValueSlotEntryWithoutCaching): Added.
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateGetOwnPropertySlotBody): Use getStaticValueSlotEntryWithoutCaching to climb up the class
+        hierarchy.
+
 2013-01-09  Kondapally Kalyan  <kalyan.kondapally@intel.com>
 
         [EFL] [WebGL] Remove GLX dependencies from X11WindowResources..
index 418d02786df8c9b1a1fdd7195911dd2102faecb6..2b111be928106517912ba65b473976c71101bbd1 100644 (file)
 #include <wtf/Noncopyable.h>
 #include <wtf/Vector.h>
 
+namespace JSC {
+
+class HashEntry;
+
+}
+
 namespace WebCore {
 
 class DOMStringList;
@@ -512,6 +518,21 @@ enum ParameterDefaultPolicy {
         return AtomicString(propertyName.publicName());
     }
 
+    template <class ThisImp>
+    inline const JSC::HashEntry* getStaticValueSlotEntryWithoutCaching(JSC::ExecState* exec, JSC::PropertyName propertyName)
+    {
+        const JSC::HashEntry* entry = ThisImp::s_info.propHashTable(exec)->entry(exec, propertyName);
+        if (!entry) // not found, forward to parent
+            return getStaticValueSlotEntryWithoutCaching<typename ThisImp::Base>(exec, propertyName);
+        return entry;
+    }
+
+    template <>
+    inline const JSC::HashEntry* getStaticValueSlotEntryWithoutCaching<JSDOMWrapper>(JSC::ExecState*, JSC::PropertyName)
+    {
+        return 0;
+    }
+
 } // namespace WebCore
 
 #endif // JSDOMBinding_h
index f97d092b08bcf2d9a0b5679b895a476f2928ccb1..e2948df33f2bdf374d4165709234b64b53a92f59 100644 (file)
@@ -402,7 +402,7 @@ sub GenerateGetOwnPropertySlotBody
     my $manualLookupGetterGeneration = sub {
         my $requiresManualLookup = $interface->extendedAttributes->{"IndexedGetter"} || $interface->extendedAttributes->{"NamedGetter"};
         if ($requiresManualLookup) {
-            push(@getOwnPropertySlotImpl, "    const ${namespaceMaybe}HashEntry* entry = ${className}Table.entry(exec, propertyName);\n");
+            push(@getOwnPropertySlotImpl, "    const ${namespaceMaybe}HashEntry* entry = getStaticValueSlotEntryWithoutCaching<$className>(exec, propertyName);\n");
             push(@getOwnPropertySlotImpl, "    if (entry) {\n");
             push(@getOwnPropertySlotImpl, "        slot.setCustom(thisObject, entry->propertyGetter());\n");
             push(@getOwnPropertySlotImpl, "        return true;\n");