diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /js/src/jit-test/tests/cacheir/string-charAt-oob.js | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/jit-test/tests/cacheir/string-charAt-oob.js')
-rw-r--r-- | js/src/jit-test/tests/cacheir/string-charAt-oob.js | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/cacheir/string-charAt-oob.js b/js/src/jit-test/tests/cacheir/string-charAt-oob.js new file mode 100644 index 0000000000..4de28d691a --- /dev/null +++ b/js/src/jit-test/tests/cacheir/string-charAt-oob.js @@ -0,0 +1,151 @@ +// Test String.prototype.charAt with out-of-bounds indices. + +function* characters(...ranges) { + for (let [start, end] of ranges) { + for (let i = start; i <= end; ++i) { + yield i; + } + } +} + +const empty = []; + +const ascii = [...characters( + [0x41, 0x5A], // A..Z + [0x61, 0x7A], // a..z +)]; + +const latin1 = [...characters( + [0xC0, 0xFF], // À..ÿ +)]; + +const twoByte = [...characters( + [0x100, 0x17E], // Ā..ž +)]; + +function atomize(s) { + return Object.keys({[s]: 0})[0]; +} + +function codePoints() { + return [empty, ascii, latin1, twoByte]; +} + +function toRope(s) { + // Ropes have at least two characters. + if (s.length < 2) { + return s; + } + if (s.length === 2) { + return newRope(s[0], s[1]); + } + return newRope(s[0], s.substring(1)); +} + +function makeStrings() { + let strings = codePoints() + .map(codePoints => String.fromCodePoint(...codePoints)) + .flatMap(x => [ + x, + toRope(x), + newString(x, {twoByte: true}), + atomize(x), + ]); + return strings; +} + +function testNegativeIndexConstant() { + let strings = makeStrings(); + for (let i = 0; i < 200; ++i) { + let str = strings[i % strings.length]; + let ch = str.charAt(-1); + assertEq(ch, ""); + } +} +for (let i = 0; i < 2; ++i) { + testNegativeIndexConstant(); +} + +function testNegativeIndexVariable() { + let indices = [-1, -2]; + let strings = makeStrings(); + for (let i = 0; i < 200; ++i) { + let str = strings[i % strings.length]; + let ch = str.charAt(indices[i & 1]); + assertEq(ch, ""); + } +} +for (let i = 0; i < 2; ++i) { + testNegativeIndexVariable(); +} + +function testNegativeOrValidIndex() { + let indices = [-1, 0]; + let strings = makeStrings(); + + // Number of string kinds created in makeStrings. + const N = 4; + + let cpoints = codePoints(); + assertEq(strings.length, cpoints.length * N); + + for (let i = 0; i < 200; ++i) { + let str = strings[i % strings.length]; + let index = indices[i & 1]; + let ch = str.charAt(index); + + let cp = cpoints[Math.trunc((i % strings.length) / N)]; + assertEq(ch, (0 <= index && index < cp.length ? String.fromCodePoint(cp[index]) : "")); + } +} +for (let i = 0; i < 2; ++i) { + testNegativeOrValidIndex(); +} + +function testTooLargeIndexConstant() { + let strings = makeStrings(); + for (let i = 0; i < 200; ++i) { + let str = strings[i % strings.length]; + let ch = str.charAt(1000); + assertEq(ch, ""); + } +} +for (let i = 0; i < 2; ++i) { + testTooLargeIndexConstant(); +} + +function testTooLargeIndexVariable() { + let indices = [1000, 2000]; + let strings = makeStrings(); + for (let i = 0; i < 200; ++i) { + let str = strings[i % strings.length]; + let ch = str.charAt(indices[i & 1]); + assertEq(ch, ""); + } +} +for (let i = 0; i < 2; ++i) { + testTooLargeIndexVariable(); +} + +function testTooLargeOrValidIndex() { + let indices = [1000, 0]; + let strings = makeStrings(); + + // Number of string kinds created in makeStrings. + const N = 4; + + let cpoints = codePoints(); + assertEq(strings.length, cpoints.length * N); + + for (let i = 0; i < 200; ++i) { + let str = strings[i % strings.length]; + let index = indices[i & 1]; + let ch = str.charAt(index); + + let cp = cpoints[Math.trunc((i % strings.length) / N)]; + assertEq(ch, (0 <= index && index < cp.length ? String.fromCodePoint(cp[index]) : "")); + } +} +for (let i = 0; i < 2; ++i) { + testTooLargeOrValidIndex(); +} |