WebKit export of https://bugs.webkit.org/show_bug.cgi?id=234538 (#35626)
diff --git a/dom/nodes/NodeList-static-length-getter-tampered-1.html b/dom/nodes/NodeList-static-length-getter-tampered-1.html
new file mode 100644
index 0000000..c5c58f9
--- /dev/null
+++ b/dom/nodes/NodeList-static-length-getter-tampered-1.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name=timeout content=long>
+<title>NodeList (static collection) "length" getter tampered</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+
+<script src="support/NodeList-static-length-tampered.js"></script>
+<script>
+test(() => {
+ const nodeList = makeStaticNodeList(100);
+
+ for (var i = 0; i < 50; i++) {
+ if (i === 25)
+ Object.defineProperty(nodeList, "length", { get() { return 10; } });
+
+ assert_equals(indexOfNodeList(nodeList), i >= 25 ? -1 : 50);
+ }
+});
+</script>
diff --git a/dom/nodes/NodeList-static-length-getter-tampered-2.html b/dom/nodes/NodeList-static-length-getter-tampered-2.html
new file mode 100644
index 0000000..bac0511
--- /dev/null
+++ b/dom/nodes/NodeList-static-length-getter-tampered-2.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name=timeout content=long>
+<title>NodeList (static collection) "length" getter tampered</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+
+<script src="support/NodeList-static-length-tampered.js"></script>
+<script>
+test(() => {
+ const nodeList = makeStaticNodeList(100);
+
+ for (var i = 0; i < 50; i++) {
+ if (i === 25)
+ Object.setPrototypeOf(nodeList, { get length() { return 10; } });
+
+ assert_equals(indexOfNodeList(nodeList), i >= 25 ? -1 : 50);
+ }
+});
+</script>
diff --git a/dom/nodes/NodeList-static-length-getter-tampered-3.html b/dom/nodes/NodeList-static-length-getter-tampered-3.html
new file mode 100644
index 0000000..9690aab
--- /dev/null
+++ b/dom/nodes/NodeList-static-length-getter-tampered-3.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name=timeout content=long>
+<title>NodeList (static collection) "length" getter tampered</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+
+<script src="support/NodeList-static-length-tampered.js"></script>
+<script>
+test(() => {
+ const nodeList = makeStaticNodeList(100);
+
+ for (var i = 0; i < 50; i++) {
+ if (i === 25)
+ Object.defineProperty(NodeList.prototype, "length", { get() { return 10; } });
+
+ assert_equals(indexOfNodeList(nodeList), i >= 25 ? -1 : 50);
+ }
+});
+</script>
diff --git a/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html b/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html
new file mode 100644
index 0000000..5ce4146
--- /dev/null
+++ b/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name=timeout content=long>
+<title>NodeList (static collection) "length" getter tampered (Array.prototype.indexOf)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+
+<script src="support/NodeList-static-length-tampered.js"></script>
+<script>
+test(() => {
+ const nodeList = makeStaticNodeList(100);
+
+ for (var i = 0; i < 50; i++) {
+ if (i === 25)
+ Object.defineProperty(nodeList, "length", { get() { return 10; } });
+
+ assert_equals(arrayIndexOfNodeList(nodeList), i >= 25 ? -1 : 50);
+ }
+});
+</script>
diff --git a/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html b/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html
new file mode 100644
index 0000000..57814ed
--- /dev/null
+++ b/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name=timeout content=long>
+<title>NodeList (static collection) "length" getter tampered (Array.prototype.indexOf)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+
+<script src="support/NodeList-static-length-tampered.js"></script>
+<script>
+test(() => {
+ const nodeList = makeStaticNodeList(100);
+
+ for (var i = 0; i < 50; i++) {
+ if (i === 25)
+ Object.setPrototypeOf(nodeList, { get length() { return 10; } });
+
+ assert_equals(arrayIndexOfNodeList(nodeList), i >= 25 ? -1 : 50);
+ }
+});
+</script>
diff --git a/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html b/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html
new file mode 100644
index 0000000..838f376
--- /dev/null
+++ b/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name=timeout content=long>
+<title>NodeList (static collection) "length" getter tampered (Array.prototype.indexOf)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+
+<script src="support/NodeList-static-length-tampered.js"></script>
+<script>
+test(() => {
+ const nodeList = makeStaticNodeList(100);
+
+ for (var i = 0; i < 50; i++) {
+ if (i === 25)
+ Object.defineProperty(NodeList.prototype, "length", { get() { return 10; } });
+
+ assert_equals(arrayIndexOfNodeList(nodeList), i >= 25 ? -1 : 50);
+ }
+});
+</script>
diff --git a/dom/nodes/support/NodeList-static-length-tampered.js b/dom/nodes/support/NodeList-static-length-tampered.js
new file mode 100644
index 0000000..51167e2
--- /dev/null
+++ b/dom/nodes/support/NodeList-static-length-tampered.js
@@ -0,0 +1,46 @@
+"use strict";
+
+function makeStaticNodeList(length) {
+ const fooRoot = document.createElement("div");
+
+ for (var i = 0; i < length; i++) {
+ const el = document.createElement("span");
+ el.className = "foo";
+ fooRoot.append(el);
+ }
+
+ document.body.append(fooRoot);
+ return fooRoot.querySelectorAll(".foo");
+}
+
+const indexOfNodeList = new Function("nodeList", `
+ const __cacheBust = ${Math.random()};
+
+ const el = nodeList[50];
+
+ let index = -1;
+
+ for (var i = 0; i < 1e5 / 2; i++) {
+ for (var j = 0; j < nodeList.length; j++) {
+ if (nodeList[j] === el) {
+ index = j;
+ break;
+ }
+ }
+ }
+
+ return index;
+`);
+
+const arrayIndexOfNodeList = new Function("nodeList", `
+ const __cacheBust = ${Math.random()};
+
+ const el = nodeList[50];
+ const {indexOf} = Array.prototype;
+
+ for (var i = 0; i < 1e5; i++) {
+ var index = indexOf.call(nodeList, el);
+ }
+
+ return index;
+`);