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;
+`);