From 80c78a9a955c3d467276fd1637f23dd69f80e01b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20Bargull?= Date: Tue, 19 Mar 2024 13:56:46 +0000 Subject: [PATCH] Bug 1885337 - Part 3: Import tests from test262 PR. r=spidermonkey-reviewers,dminor Differential Revision: https://phabricator.services.mozilla.com/D204638 --- js/src/tests/test262-update.py | 2 + js/src/tests/test262/prs/3994/browser.js | 0 .../prs/3994/built-ins/Uint8Array/browser.js | 0 .../built-ins/Uint8Array/fromBase64/alphabet.js | 25 + .../built-ins/Uint8Array/fromBase64/browser.js | 0 .../built-ins/Uint8Array/fromBase64/descriptor.js | 18 + .../Uint8Array/fromBase64/ignores-receiver.js | 22 + .../Uint8Array/fromBase64/illegal-characters.js | 26 + .../Uint8Array/fromBase64/last-chunk-handling.js | 67 ++ .../3994/built-ins/Uint8Array/fromBase64/length.js | 19 + .../3994/built-ins/Uint8Array/fromBase64/name.js | 19 + .../Uint8Array/fromBase64/nonconstructor.js | 18 + .../Uint8Array/fromBase64/option-coercion.js | 62 ++ .../built-ins/Uint8Array/fromBase64/results.js | 30 + .../3994/built-ins/Uint8Array/fromBase64/shell.js | 24 + .../Uint8Array/fromBase64/string-coercion.js | 44 ++ .../built-ins/Uint8Array/fromBase64/whitespace.js | 25 + .../3994/built-ins/Uint8Array/fromHex/browser.js | 0 .../built-ins/Uint8Array/fromHex/descriptor.js | 18 + .../Uint8Array/fromHex/ignores-receiver.js | 22 + .../Uint8Array/fromHex/illegal-characters.js | 28 + .../3994/built-ins/Uint8Array/fromHex/length.js | 19 + .../prs/3994/built-ins/Uint8Array/fromHex/name.js | 19 + .../built-ins/Uint8Array/fromHex/nonconstructor.js | 18 + .../Uint8Array/fromHex/odd-length-input.js | 14 + .../3994/built-ins/Uint8Array/fromHex/results.js | 31 + .../prs/3994/built-ins/Uint8Array/fromHex/shell.js | 24 + .../Uint8Array/fromHex/string-coercion.js | 23 + .../3994/built-ins/Uint8Array/prototype/browser.js | 0 .../Uint8Array/prototype/setFromBase64/alphabet.js | 44 ++ .../Uint8Array/prototype/setFromBase64/browser.js | 0 .../prototype/setFromBase64/descriptor.js | 18 + .../prototype/setFromBase64/detached-buffer.js | 32 + .../prototype/setFromBase64/illegal-characters.js | 27 + .../prototype/setFromBase64/last-chunk-handling.js | 156 +++++ .../Uint8Array/prototype/setFromBase64/length.js | 19 + .../Uint8Array/prototype/setFromBase64/name.js | 19 + .../prototype/setFromBase64/nonconstructor.js | 19 + .../prototype/setFromBase64/option-coercion.js | 72 ++ .../Uint8Array/prototype/setFromBase64/results.js | 33 + .../Uint8Array/prototype/setFromBase64/shell.js | 42 ++ .../prototype/setFromBase64/string-coercion.js | 46 ++ .../Uint8Array/prototype/setFromBase64/subarray.js | 20 + .../prototype/setFromBase64/target-size.js | 67 ++ .../prototype/setFromBase64/whitespace.js | 26 + .../Uint8Array/prototype/setFromHex/browser.js | 0 .../Uint8Array/prototype/setFromHex/descriptor.js | 18 + .../prototype/setFromHex/detached-buffer.js | 17 + .../prototype/setFromHex/illegal-characters.js | 29 + .../Uint8Array/prototype/setFromHex/length.js | 19 + .../Uint8Array/prototype/setFromHex/name.js | 19 + .../prototype/setFromHex/nonconstructor.js | 19 + .../Uint8Array/prototype/setFromHex/results.js | 34 + .../Uint8Array/prototype/setFromHex/shell.js | 42 ++ .../prototype/setFromHex/string-coercion.js | 24 + .../Uint8Array/prototype/setFromHex/subarray.js | 20 + .../Uint8Array/prototype/setFromHex/target-size.js | 32 + .../3994/built-ins/Uint8Array/prototype/shell.js | 0 .../Uint8Array/prototype/toBase64/alphabet.js | 20 + .../Uint8Array/prototype/toBase64/browser.js | 0 .../Uint8Array/prototype/toBase64/descriptor.js | 18 + .../prototype/toBase64/detached-buffer.js | 42 ++ .../Uint8Array/prototype/toBase64/length.js | 19 + .../Uint8Array/prototype/toBase64/name.js | 19 + .../prototype/toBase64/nonconstructor.js | 19 + .../prototype/toBase64/option-coercion.js | 51 ++ .../prototype/toBase64/receiver-not-uint8array.js | 36 + .../Uint8Array/prototype/toBase64/results.js | 19 + .../Uint8Array/prototype/toBase64/shell.js | 203 ++++++ .../Uint8Array/prototype/toHex/browser.js | 0 .../Uint8Array/prototype/toHex/descriptor.js | 18 + .../Uint8Array/prototype/toHex/detached-buffer.js | 18 + .../built-ins/Uint8Array/prototype/toHex/length.js | 19 + .../built-ins/Uint8Array/prototype/toHex/name.js | 19 + .../Uint8Array/prototype/toHex/nonconstructor.js | 19 + .../prototype/toHex/receiver-not-uint8array.js | 29 + .../Uint8Array/prototype/toHex/results.js | 18 + .../built-ins/Uint8Array/prototype/toHex/shell.js | 203 ++++++ .../test262/prs/3994/built-ins/Uint8Array/shell.js | 0 js/src/tests/test262/prs/3994/built-ins/browser.js | 0 js/src/tests/test262/prs/3994/built-ins/shell.js | 0 js/src/tests/test262/prs/3994/shell.js | 723 +++++++++++++++++++++ 82 files changed, 3042 insertions(+) create mode 100644 js/src/tests/test262/prs/3994/browser.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/browser.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/alphabet.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/browser.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/descriptor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/ignores-receiver.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/illegal-characters.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/last-chunk-handling.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/length.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/name.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/nonconstructor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/option-coercion.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/results.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/shell.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/string-coercion.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/whitespace.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/browser.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/descriptor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/ignores-receiver.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/illegal-characters.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/length.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/name.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/nonconstructor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/odd-length-input.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/results.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/shell.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/string-coercion.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/browser.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/browser.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/length.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/name.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/results.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/shell.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/subarray.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/target-size.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/browser.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/descriptor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/length.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/name.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/results.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/shell.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/subarray.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/target-size.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/shell.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/alphabet.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/browser.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/descriptor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/length.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/name.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/option-coercion.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/results.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/shell.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/browser.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/descriptor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/detached-buffer.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/length.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/name.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/nonconstructor.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/results.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/shell.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/Uint8Array/shell.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/browser.js create mode 100644 js/src/tests/test262/prs/3994/built-ins/shell.js create mode 100644 js/src/tests/test262/prs/3994/shell.js diff --git a/js/src/tests/test262-update.py b/js/src/tests/test262-update.py index fc6fa62c4542..d84916f00544 100755 --- a/js/src/tests/test262-update.py +++ b/js/src/tests/test262-update.py @@ -38,6 +38,7 @@ FEATURE_CHECK_NEEDED = { "iterator-helpers": "!this.hasOwnProperty('Iterator')", # Bug 1568906 "Intl.Segmenter": "!Intl.Segmenter", # Bug 1423593 "resizable-arraybuffer": "!ArrayBuffer.prototype.resize", # Bug 1670026 + "uint8array-base64": "!Uint8Array.fromBase64", # Bug 1862220 } RELEASE_OR_BETA = set( [ @@ -51,6 +52,7 @@ SHELL_OPTIONS = { "iterator-helpers": "--enable-iterator-helpers", "symbols-as-weakmap-keys": "--enable-symbols-as-weakmap-keys", "resizable-arraybuffer": "--enable-arraybuffer-resizable", + "uint8array-base64": "--enable-uint8array-base64", } diff --git a/js/src/tests/test262/prs/3994/browser.js b/js/src/tests/test262/prs/3994/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/alphabet.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/alphabet.js new file mode 100644 index 000000000000..c893bf952a5a --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/alphabet.js @@ -0,0 +1,25 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: Conversion of base64 strings to Uint8Arrays exercising the alphabet option +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +assert.compareArray(Uint8Array.fromBase64('x+/y'), [199, 239, 242]); +assert.compareArray(Uint8Array.fromBase64('x+/y', { alphabet: 'base64' }), [199, 239, 242]); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('x+/y', { alphabet: 'base64url' }); +}); + +assert.compareArray(Uint8Array.fromBase64('x-_y', { alphabet: 'base64url' }), [199, 239, 242]); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('x-_y'); +}); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('x-_y', { alphabet: 'base64' }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/descriptor.js new file mode 100644 index 000000000000..a0e843cfafd9 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/descriptor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: > + Uint8Array.fromBase64 has default data property attributes. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array, 'fromBase64', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/ignores-receiver.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/ignores-receiver.js new file mode 100644 index 000000000000..0847653d63ce --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/ignores-receiver.js @@ -0,0 +1,22 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: Uint8Array.fromBase64 ignores its receiver +features: [uint8array-base64, TypedArray] +---*/ + +var fromBase64 = Uint8Array.fromBase64; +var noReceiver = fromBase64("Zg=="); +assert.sameValue(Object.getPrototypeOf(noReceiver), Uint8Array.prototype); + +class Subclass extends Uint8Array { + constructor() { + throw new Test262Error("subclass constructor called"); + } +} +var fromSubclass = Subclass.fromBase64("Zg=="); +assert.sameValue(Object.getPrototypeOf(fromSubclass), Uint8Array.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/illegal-characters.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/illegal-characters.js new file mode 100644 index 000000000000..6c2d6eef4a1f --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/illegal-characters.js @@ -0,0 +1,26 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: Uint8Array.fromBase64 throws a SyntaxError when input has non-base64, non-ascii-whitespace characters +features: [uint8array-base64, TypedArray] +---*/ + +var illegal = [ + 'Zm.9v', + 'Zm9v^', + 'Zg==&', + 'Z−==', // U+2212 'Minus Sign' + 'Z+==', // U+FF0B 'Fullwidth Plus Sign' + 'Zg\u00A0==', // nbsp + 'Zg\u2009==', // thin space + 'Zg\u2028==', // line separator +]; +illegal.forEach(function(value) { + assert.throws(SyntaxError, function() { + Uint8Array.fromBase64(value) + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/last-chunk-handling.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/last-chunk-handling.js new file mode 100644 index 000000000000..c78d15e86948 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/last-chunk-handling.js @@ -0,0 +1,67 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: Handling of final chunks in Uint8Array.fromBase64 +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +// padding +assert.compareArray(Uint8Array.fromBase64('ZXhhZg=='), [101, 120, 97, 102]); +assert.compareArray(Uint8Array.fromBase64('ZXhhZg==', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]); +assert.compareArray(Uint8Array.fromBase64('ZXhhZg==', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97, 102]); +assert.compareArray(Uint8Array.fromBase64('ZXhhZg==', { lastChunkHandling: 'strict' }), [101, 120, 97, 102]); + +// no padding +assert.compareArray(Uint8Array.fromBase64('ZXhhZg'), [101, 120, 97, 102]); +assert.compareArray(Uint8Array.fromBase64('ZXhhZg', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]); +assert.compareArray(Uint8Array.fromBase64('ZXhhZg', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97]); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('ZXhhZg', { lastChunkHandling: 'strict' }); +}); + +// non-zero padding bits +assert.compareArray(Uint8Array.fromBase64('ZXhhZh=='), [101, 120, 97, 102]); +assert.compareArray(Uint8Array.fromBase64('ZXhhZh==', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]); +assert.compareArray(Uint8Array.fromBase64('ZXhhZh==', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97, 102]); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('ZXhhZh==', { lastChunkHandling: 'strict' }); +}); + +// non-zero padding bits, no padding +assert.compareArray(Uint8Array.fromBase64('ZXhhZh'), [101, 120, 97, 102]); +assert.compareArray(Uint8Array.fromBase64('ZXhhZh', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]); +assert.compareArray(Uint8Array.fromBase64('ZXhhZh', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97]); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('ZXhhZh', { lastChunkHandling: 'strict' }); +}); + +// partial padding +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('ZXhhZg='); +}); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('ZXhhZg=', { lastChunkHandling: 'loose' }); +}); +assert.compareArray(Uint8Array.fromBase64('ZXhhZg=', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97]); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('ZXhhZg=', { lastChunkHandling: 'strict' }); +}); + +// excess padding +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('ZXhhZg==='); +}); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('ZXhhZg===', { lastChunkHandling: 'loose' }); +}); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('ZXhhZg===', { lastChunkHandling: 'stop-before-partial' }); +}); +assert.throws(SyntaxError, function() { + Uint8Array.fromBase64('ZXhhZg===', { lastChunkHandling: 'strict' }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/length.js new file mode 100644 index 000000000000..dab9b49f617b --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/length.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: > + Uint8Array.fromBase64.length is 1. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.fromBase64, 'length', { + value: 1, + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/name.js new file mode 100644 index 000000000000..2bd67168636a --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/name.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: > + Uint8Array.fromBase64.name is "fromBase64". +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.fromBase64, 'name', { + value: 'fromBase64', + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/nonconstructor.js new file mode 100644 index 000000000000..7546b12b6b09 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/nonconstructor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: > + Uint8Array.fromBase64 is not a constructor function. +includes: [isConstructor.js] +features: [uint8array-base64, TypedArray, Reflect.construct] +---*/ + +assert(!isConstructor(Uint8Array.fromBase64), "Uint8Array.fromBase64 is not a constructor"); + +assert.throws(TypeError, function() { + new Uint8Array.fromBase64(''); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/option-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/option-coercion.js new file mode 100644 index 000000000000..e314a8f16f61 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/option-coercion.js @@ -0,0 +1,62 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: Uint8Array.fromBase64 triggers effects of the "alphabet" and "lastChunkHandling" getters, but does not perform toString on the results +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +assert.throws(TypeError, function() { + Uint8Array.fromBase64("Zg==", { alphabet: Object("base64") }); +}); + +assert.throws(TypeError, function() { + Uint8Array.fromBase64("Zg==", { lastChunkHandling: Object("loose") }); +}); + + +var toStringCalls = 0; +var throwyToString = { + toString: function() { + toStringCalls += 1; + throw new Test262Error("toString called"); + } +}; +assert.throws(TypeError, function() { + Uint8Array.fromBase64("Zg==", { alphabet: throwyToString }); +}); +assert.sameValue(toStringCalls, 0); + +assert.throws(TypeError, function() { + Uint8Array.fromBase64("Zg==", { lastChunkHandling: throwyToString }); +}); +assert.sameValue(toStringCalls, 0); + + +var alphabetAccesses = 0; +var base64UrlOptions = {}; +Object.defineProperty(base64UrlOptions, "alphabet", { + get: function() { + alphabetAccesses += 1; + return "base64url"; + } +}); +var arr = Uint8Array.fromBase64("x-_y", base64UrlOptions); +assert.compareArray(arr, [199, 239, 242]); +assert.sameValue(alphabetAccesses, 1); + +var lastChunkHandlingAccesses = 0; +var strictOptions = {}; +Object.defineProperty(strictOptions, "lastChunkHandling", { + get: function() { + lastChunkHandlingAccesses += 1; + return "strict"; + } +}); +var arr = Uint8Array.fromBase64("Zg==", strictOptions); +assert.compareArray(arr, [102]); +assert.sameValue(lastChunkHandlingAccesses, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/results.js new file mode 100644 index 000000000000..9d19507f9ac7 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/results.js @@ -0,0 +1,30 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: Conversion of base64 strings to Uint8Arrays +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +// standard test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10 +var standardBase64Vectors = [ + ["", []], + ["Zg==", [102]], + ["Zm8=", [102, 111]], + ["Zm9v", [102, 111, 111]], + ["Zm9vYg==", [102, 111, 111, 98]], + ["Zm9vYmE=", [102, 111, 111, 98, 97]], + ["Zm9vYmFy", [102, 111, 111, 98, 97, 114]], +]; + +standardBase64Vectors.forEach(function (pair) { + var arr = Uint8Array.fromBase64(pair[0]); + assert.sameValue(Object.getPrototypeOf(arr), Uint8Array.prototype, "decoding " + pair[0]); + assert.sameValue(arr.length, pair[1].length, "decoding " + pair[0]); + assert.sameValue(arr.buffer.byteLength, pair[1].length, "decoding " + pair[0]); + assert.compareArray(arr, pair[1], "decoding " + pair[0]); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/shell.js new file mode 100644 index 000000000000..eda147728252 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/string-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/string-coercion.js new file mode 100644 index 000000000000..57292f8a9848 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/string-coercion.js @@ -0,0 +1,44 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: Uint8Array.fromBase64 throws if its argument is not a string +features: [uint8array-base64, TypedArray] +---*/ + +var toStringCalls = 0; +var throwyToString = { + toString: function() { + toStringCalls += 1; + throw new Test262Error("toString called"); + } +}; + +assert.throws(TypeError, function() { + Uint8Array.fromBase64(throwyToString); +}); +assert.sameValue(toStringCalls, 0); + + +var optionAccesses = 0; +var touchyOptions = {}; +Object.defineProperty(touchyOptions, "alphabet", { + get: function() { + optionAccesses += 1; + throw new Test262Error("alphabet accessed"); + } +}); +Object.defineProperty(touchyOptions, "lastChunkHandling", { + get: function() { + optionAccesses += 1; + throw new Test262Error("lastChunkHandling accessed"); + } +}); +assert.throws(TypeError, function() { + Uint8Array.fromBase64(throwyToString, touchyOptions); +}); +assert.sameValue(toStringCalls, 0); +assert.sameValue(optionAccesses, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/whitespace.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/whitespace.js new file mode 100644 index 000000000000..87c79a656318 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/whitespace.js @@ -0,0 +1,25 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.frombase64 +description: Uint8Array.fromBase64 ignores ASCII whitespace in the input +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +var whitespaceKinds = [ + ["Z g==", "space"], + ["Z\tg==", "tab"], + ["Z\x0Ag==", "LF"], + ["Z\x0Cg==", "FF"], + ["Z\x0Dg==", "CR"], +]; +whitespaceKinds.forEach(function(pair) { + var arr = Uint8Array.fromBase64(pair[0]); + assert.sameValue(arr.length, 1); + assert.sameValue(arr.buffer.byteLength, 1); + assert.compareArray(arr, [102], "ascii whitespace: " + pair[1]); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/descriptor.js new file mode 100644 index 000000000000..3d5365205491 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/descriptor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.fromhex +description: > + Uint8Array.fromHex has default data property attributes. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array, 'fromHex', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/ignores-receiver.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/ignores-receiver.js new file mode 100644 index 000000000000..421a0278d74b --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/ignores-receiver.js @@ -0,0 +1,22 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.fromhex +description: Uint8Array.fromHex ignores its receiver +features: [uint8array-base64, TypedArray] +---*/ + +var fromHex = Uint8Array.fromHex; +var noReceiver = fromHex("aa"); +assert.sameValue(Object.getPrototypeOf(noReceiver), Uint8Array.prototype); + +class Subclass extends Uint8Array { + constructor() { + throw new Test262Error("subclass constructor called"); + } +} +var fromSubclass = Subclass.fromHex("aa"); +assert.sameValue(Object.getPrototypeOf(fromSubclass), Uint8Array.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/illegal-characters.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/illegal-characters.js new file mode 100644 index 000000000000..718801e4c76d --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/illegal-characters.js @@ -0,0 +1,28 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.fromhex +description: Uint8Array.fromHex throws a SyntaxError when input has non-hex characters +features: [uint8array-base64, TypedArray] +---*/ + +var illegal = [ + 'a.a', + 'aa^', + 'a a', + 'a\ta', + 'a\x0Aa', + 'a\x0Ca', + 'a\x0Da', + 'a\u00A0a', // nbsp + 'a\u2009a', // thin space + 'a\u2028a', // line separator +]; +illegal.forEach(function(value) { + assert.throws(SyntaxError, function() { + Uint8Array.fromHex(value) + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/length.js new file mode 100644 index 000000000000..9108a1c2c123 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/length.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.fromhex +description: > + Uint8Array.fromHex.length is 1. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.fromHex, 'length', { + value: 1, + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/name.js new file mode 100644 index 000000000000..7d4e14534950 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/name.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.fromhex +description: > + Uint8Array.fromHex.name is "fromHex". +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.fromHex, 'name', { + value: 'fromHex', + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/nonconstructor.js new file mode 100644 index 000000000000..6e34171e778b --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/nonconstructor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.fromhex +description: > + Uint8Array.fromHex is not a constructor function. +includes: [isConstructor.js] +features: [uint8array-base64, TypedArray, Reflect.construct] +---*/ + +assert(!isConstructor(Uint8Array.fromHex), "Uint8Array.fromHex is not a constructor"); + +assert.throws(TypeError, function() { + new Uint8Array.fromHex(''); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/odd-length-input.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/odd-length-input.js new file mode 100644 index 000000000000..fe7860a08306 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/odd-length-input.js @@ -0,0 +1,14 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.fromhex +description: Uint8Array.fromHex throws if given an odd number of input hex characters +features: [uint8array-base64, TypedArray] +---*/ + +assert.throws(SyntaxError, function() { + Uint8Array.fromHex('a'); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/results.js new file mode 100644 index 000000000000..d40beab7cd20 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/results.js @@ -0,0 +1,31 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.fromhex +description: Conversion of hex strings to Uint8Arrays +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +var cases = [ + ["", []], + ["66", [102]], + ["666f", [102, 111]], + ["666F", [102, 111]], + ["666f6f", [102, 111, 111]], + ["666F6f", [102, 111, 111]], + ["666f6f62", [102, 111, 111, 98]], + ["666f6f6261", [102, 111, 111, 98, 97]], + ["666f6f626172", [102, 111, 111, 98, 97, 114]], +]; + +cases.forEach(function (pair) { + var arr = Uint8Array.fromHex(pair[0]); + assert.sameValue(Object.getPrototypeOf(arr), Uint8Array.prototype, "decoding " + pair[0]); + assert.sameValue(arr.length, pair[1].length, "decoding " + pair[0]); + assert.sameValue(arr.buffer.byteLength, pair[1].length, "decoding " + pair[0]); + assert.compareArray(arr, pair[1], "decoding " + pair[0]); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/shell.js new file mode 100644 index 000000000000..eda147728252 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/string-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/string-coercion.js new file mode 100644 index 000000000000..fea57227fc3c --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/string-coercion.js @@ -0,0 +1,23 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.fromhex +description: Uint8Array.fromHex throws if its argument is not a string +features: [uint8array-base64, TypedArray] +---*/ + +var toStringCalls = 0; +var throwyToString = { + toString: function() { + toStringCalls += 1; + throw new Test262Error("toString called"); + } +}; + +assert.throws(TypeError, function() { + Uint8Array.fromHex(throwyToString); +}); +assert.sameValue(toStringCalls, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js new file mode 100644 index 000000000000..bb4acdb8f2ec --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js @@ -0,0 +1,44 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Conversion of base64 strings to Uint8Arrays exercising the alphabet option +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +var target = new Uint8Array([255, 255, 255, 255]); +var result = target.setFromBase64('x+/y'); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(target, [199, 239, 242, 255]); + +var target = new Uint8Array([255, 255, 255, 255]); +var result = target.setFromBase64('x+/y', { alphabet: 'base64' }); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(target, [199, 239, 242, 255]); + +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255]); + target.setFromBase64('x+/y', { alphabet: 'base64url' }); +}); + + +var target = new Uint8Array([255, 255, 255, 255]); +var result = target.setFromBase64('x-_y', { alphabet: 'base64url' }); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(target, [199, 239, 242, 255]); + +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255]); + target.setFromBase64('x-_y'); +}); +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255]); + target.setFromBase64('x-_y', { alphabet: 'base64' }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js new file mode 100644 index 000000000000..bd319f7d439a --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: > + Uint8Array.prototype.setFromBase64 has default data property attributes. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype, 'setFromBase64', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js new file mode 100644 index 000000000000..3dd042bb028d --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js @@ -0,0 +1,32 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Uint8Array.prototype.setFromBase64 throws on detatched buffers +includes: [detachArrayBuffer.js] +features: [uint8array-base64, TypedArray] +---*/ + +var target = new Uint8Array([255, 255, 255]); +$DETACHBUFFER(target.buffer); +assert.throws(TypeError, function() { + target.setFromBase64('Zg=='); +}); + +var getterCalls = 0; +var targetDetachingOptions = {}; +Object.defineProperty(targetDetachingOptions, 'alphabet', { + get: function() { + getterCalls += 1; + $DETACHBUFFER(target.buffer); + return "base64"; + } +}); +var target = new Uint8Array([255, 255, 255]); +assert.throws(TypeError, function() { + target.setFromBase64('Zg==', targetDetachingOptions); +}); +assert.sameValue(getterCalls, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js new file mode 100644 index 000000000000..9c6b827df856 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js @@ -0,0 +1,27 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Uint8Array.prototype.setFromBase64 throws a SyntaxError when input has non-base64, non-ascii-whitespace characters +features: [uint8array-base64, TypedArray] +---*/ + +var illegal = [ + 'Zm.9v', + 'Zm9v^', + 'Zg==&', + 'Z−==', // U+2212 'Minus Sign' + 'Z+==', // U+FF0B 'Fullwidth Plus Sign' + 'Zg\u00A0==', // nbsp + 'Zg\u2009==', // thin space + 'Zg\u2028==', // line separator +]; +illegal.forEach(function(value) { + assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255]); + target.setFromBase64(value); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js new file mode 100644 index 000000000000..958a89b10ebe --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js @@ -0,0 +1,156 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Handling of final chunks in target.setFromBase64 +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +// padding +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZg=='); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZg==', { lastChunkHandling: 'loose' }); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZg==', { lastChunkHandling: 'stop-before-partial' }); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZg==', { lastChunkHandling: 'strict' }); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + + +// no padding +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZg'); +assert.sameValue(result.read, 6); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZg', { lastChunkHandling: 'loose' }); +assert.sameValue(result.read, 6); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZg', { lastChunkHandling: 'stop-before-partial' }); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(target, [101, 120, 97, 255, 255, 255]); + +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255, 255]); + target.setFromBase64('ZXhhZg', { lastChunkHandling: 'strict' }); +}); + + +// non-zero padding bits +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZh=='); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZh==', { lastChunkHandling: 'loose' }); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZh==', { lastChunkHandling: 'stop-before-partial' }); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255, 255]); + target.setFromBase64('ZXhhZh==', { lastChunkHandling: 'strict' }); +}); + + +// non-zero padding bits, no padding +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZh'); +assert.sameValue(result.read, 6); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZh', { lastChunkHandling: 'loose' }); +assert.sameValue(result.read, 6); +assert.sameValue(result.written, 4); +assert.compareArray(target, [101, 120, 97, 102, 255, 255]); + +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZh', { lastChunkHandling: 'stop-before-partial' }); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(target, [101, 120, 97, 255, 255, 255]); + +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255, 255]); + target.setFromBase64('ZXhhZh', { lastChunkHandling: 'strict' }); +}); + + +// partial padding +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255, 255]); + target.setFromBase64('ZXhhZg='); +}); + +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255, 255]); + target.setFromBase64('ZXhhZg=', { lastChunkHandling: 'loose' }); +}); + +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('ZXhhZg=', { lastChunkHandling: 'stop-before-partial' }); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(target, [101, 120, 97, 255, 255, 255]); + +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255, 255]); + target.setFromBase64('ZXhhZg=', { lastChunkHandling: 'strict' }); +}); + + +// excess padding +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255, 255]); + target.setFromBase64('ZXhhZg==='); +}); + +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255, 255]); + target.setFromBase64('ZXhhZg===', { lastChunkHandling: 'loose' }); +}); + +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255, 255]); + target.setFromBase64('ZXhhZg===', { lastChunkHandling: 'stop-before-partial' }); +}); + +assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255, 255]); + target.setFromBase64('ZXhhZg===', { lastChunkHandling: 'strict' }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/length.js new file mode 100644 index 000000000000..df97101a14ea --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/length.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: > + Uint8Array.prototype.setFromBase64.length is 1. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype.setFromBase64, 'length', { + value: 1, + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/name.js new file mode 100644 index 000000000000..c38be745320f --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/name.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: > + Uint8Array.prototype.setFromBase64.name is "setFromBase64". +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype.setFromBase64, 'name', { + value: 'setFromBase64', + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js new file mode 100644 index 000000000000..46f5078ff513 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: > + Uint8Array.prototype.setFromBase64 is not a constructor function. +includes: [isConstructor.js] +features: [uint8array-base64, TypedArray, Reflect.construct] +---*/ + +assert(!isConstructor(Uint8Array.prototype.setFromBase64), "Uint8Array.prototype.setFromBase64 is not a constructor"); + +assert.throws(TypeError, function() { + var target = new Uint8Array(10); + new target.setFromBase64(''); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js new file mode 100644 index 000000000000..90bd1e330dcd --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js @@ -0,0 +1,72 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Uint8Array.prototype.setFromBase64 triggers effects of the "alphabet" and "lastChunkHandling" getters, but does not perform toString on the results +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +assert.throws(TypeError, function() { + var target = new Uint8Array([255, 255, 255]); + target.setFromBase64("Zg==", { alphabet: Object("base64") }); +}); + +assert.throws(TypeError, function() { + var target = new Uint8Array([255, 255, 255]); + target.setFromBase64("Zg==", { lastChunkHandling: Object("strict") }); +}); + + +var toStringCalls = 0; +var throwyToString = { + toString: function() { + toStringCalls += 1; + throw new Test262Error("toString called"); + } +}; +assert.throws(TypeError, function() { + var target = new Uint8Array([255, 255, 255]); + target.setFromBase64("Zg==", { alphabet: throwyToString }); +}); +assert.sameValue(toStringCalls, 0); + +assert.throws(TypeError, function() { + var target = new Uint8Array([255, 255, 255]); + target.setFromBase64("Zg==", { lastChunkHandling: throwyToString }); +}); +assert.sameValue(toStringCalls, 0); + + +var alphabetAccesses = 0; +var base64UrlOptions = {}; +Object.defineProperty(base64UrlOptions, "alphabet", { + get: function() { + alphabetAccesses += 1; + return "base64url"; + } +}); +var target = new Uint8Array([255, 255, 255, 255]); +var result = target.setFromBase64("x-_y", base64UrlOptions); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(target, [199, 239, 242, 255]); +assert.sameValue(alphabetAccesses, 1); + +var lastChunkHandlingAccesses = 0; +var strictOptions = {}; +Object.defineProperty(strictOptions, "lastChunkHandling", { + get: function() { + lastChunkHandlingAccesses += 1; + return "strict"; + } +}); +var target = new Uint8Array([255, 255, 255, 255]); +var result = target.setFromBase64("Zg==", strictOptions); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 1); +assert.compareArray(target, [102, 255, 255, 255]); +assert.sameValue(lastChunkHandlingAccesses, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/results.js new file mode 100644 index 000000000000..2c39bab31855 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/results.js @@ -0,0 +1,33 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Conversion of base64 strings to Uint8Arrays +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +// standard test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10 +var standardBase64Vectors = [ + ["", []], + ["Zg==", [102]], + ["Zm8=", [102, 111]], + ["Zm9v", [102, 111, 111]], + ["Zm9vYg==", [102, 111, 111, 98]], + ["Zm9vYmE=", [102, 111, 111, 98, 97]], + ["Zm9vYmFy", [102, 111, 111, 98, 97, 114]], +]; + +standardBase64Vectors.forEach(function (pair) { + var allFF = [255, 255, 255, 255, 255, 255, 255, 255]; + var target = new Uint8Array(allFF); + var result = target.setFromBase64(pair[0]); + assert.sameValue(result.read, pair[0].length); + assert.sameValue(result.written, pair[1].length); + + var expected = pair[1].concat(allFF.slice(pair[1].length)) + assert.compareArray(target, expected, "decoding " + pair[0]); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/shell.js new file mode 100644 index 000000000000..a7590326c360 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/shell.js @@ -0,0 +1,42 @@ +// GENERATED, DO NOT EDIT +// file: detachArrayBuffer.js +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + A function used in the process of asserting correctness of TypedArray objects. + + $262.detachArrayBuffer is defined by a host. +defines: [$DETACHBUFFER] +---*/ + +function $DETACHBUFFER(buffer) { + if (!$262 || typeof $262.detachArrayBuffer !== "function") { + throw new Test262Error("No method available to detach an ArrayBuffer"); + } + $262.detachArrayBuffer(buffer); +} + +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js new file mode 100644 index 000000000000..7c479a78cdf7 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js @@ -0,0 +1,46 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Uint8Array.prototype.setFromBase64 throws if its first argument is not a string +features: [uint8array-base64, TypedArray] +---*/ + +var toStringCalls = 0; +var throwyToString = { + toString: function() { + toStringCalls += 1; + throw new Test262Error("toString called"); + } +}; + +assert.throws(TypeError, function() { + var target = new Uint8Array(10); + target.setFromBase64(throwyToString); +}); +assert.sameValue(toStringCalls, 0); + + +var optionAccesses = 0; +var touchyOptions = {}; +Object.defineProperty(touchyOptions, "alphabet", { + get: function() { + optionAccesses += 1; + throw new Test262Error("alphabet accessed"); + } +}); +Object.defineProperty(touchyOptions, "lastChunkHandling", { + get: function() { + optionAccesses += 1; + throw new Test262Error("lastChunkHandling accessed"); + } +}); +assert.throws(TypeError, function() { + var target = new Uint8Array(10); + target.setFromBase64(throwyToString, touchyOptions); +}); +assert.sameValue(toStringCalls, 0); +assert.sameValue(optionAccesses, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/subarray.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/subarray.js new file mode 100644 index 000000000000..ffffd227b962 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/subarray.js @@ -0,0 +1,20 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Uint8Array.prototype.setFromBase64 takes into account the offset of the target Uint8Array +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +var base = new Uint8Array([255, 255, 255, 255, 255, 255, 255]); +var subarray = base.subarray(2, 5); + +var result = subarray.setFromBase64('Zm9vYmFy'); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(subarray, [102, 111, 111]); +assert.compareArray(base, [255, 255, 102, 111, 111, 255, 255]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/target-size.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/target-size.js new file mode 100644 index 000000000000..4e38423621ef --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/target-size.js @@ -0,0 +1,67 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Uint8Array.prototype.setFromBase64 behavior when target buffer is small +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +// buffer too small +var target = new Uint8Array([255, 255, 255, 255, 255]); +var result = target.setFromBase64('Zm9vYmFy'); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(target, [102, 111, 111, 255, 255]); + +// buffer too small, padded +var target = new Uint8Array([255, 255, 255, 255]); +var result = target.setFromBase64('Zm9vYmE='); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(target, [102, 111, 111, 255]); + +// buffer exact +var target = new Uint8Array([255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('Zm9vYmFy'); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 6); +assert.compareArray(target, [102, 111, 111, 98, 97, 114]); + +// buffer exact, padded +var target = new Uint8Array([255, 255, 255, 255, 255]); +var result = target.setFromBase64('Zm9vYmE='); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 5); +assert.compareArray(target, [102, 111, 111, 98, 97]); + +// buffer exact, not padded +var target = new Uint8Array([255, 255, 255, 255, 255]); +var result = target.setFromBase64('Zm9vYmE'); +assert.sameValue(result.read, 7); +assert.sameValue(result.written, 5); +assert.compareArray(target, [102, 111, 111, 98, 97]); + +// buffer exact, padded, stop-before-partial +var target = new Uint8Array([255, 255, 255, 255, 255]); +var result = target.setFromBase64('Zm9vYmE=', { lastChunkHandling: 'stop-before-partial' }); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 5); +assert.compareArray(target, [102, 111, 111, 98, 97]); + +// buffer exact, not padded, stop-before-partial +var target = new Uint8Array([255, 255, 255, 255, 255]); +var result = target.setFromBase64('Zm9vYmE', { lastChunkHandling: 'stop-before-partial' }); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 3); +assert.compareArray(target, [102, 111, 111, 255, 255]); + +// buffer too large +var target = new Uint8Array([255, 255, 255, 255, 255, 255, 255]); +var result = target.setFromBase64('Zm9vYmFy'); +assert.sameValue(result.read, 8); +assert.sameValue(result.written, 6); +assert.compareArray(target, [102, 111, 111, 98, 97, 114, 255]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js new file mode 100644 index 000000000000..a09673d2bd4c --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js @@ -0,0 +1,26 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Uint8Array.prototype.setFromBase64 ignores ASCII whitespace in the input +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +var whitespaceKinds = [ + ["Z g==", "space"], + ["Z\tg==", "tab"], + ["Z\x0Ag==", "LF"], + ["Z\x0Cg==", "FF"], + ["Z\x0Dg==", "CR"], +]; +whitespaceKinds.forEach(function(pair) { + var target = new Uint8Array([255, 255, 255]); + var result = target.setFromBase64(pair[0]); + assert.sameValue(result.read, 5); + assert.sameValue(result.written, 1); + assert.compareArray(target, [102, 255, 255], "ascii whitespace: " + pair[1]); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/descriptor.js new file mode 100644 index 000000000000..3d1a4c996a18 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/descriptor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfromhex +description: > + Uint8Array.prototype.setFromHex has default data property attributes. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype, 'setFromHex', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js new file mode 100644 index 000000000000..5ba8e15727be --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js @@ -0,0 +1,17 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfromhex +description: Uint8Array.prototype.setFromHex throws on detatched buffers +includes: [detachArrayBuffer.js] +features: [uint8array-base64, TypedArray] +---*/ + +var target = new Uint8Array([255, 255, 255]); +$DETACHBUFFER(target.buffer); +assert.throws(TypeError, function() { + target.setFromHex('aa'); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js new file mode 100644 index 000000000000..1c30b4cffd56 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js @@ -0,0 +1,29 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfromhex +description: Uint8Array.prototype.setFromHex throws a SyntaxError when input has non-hex characters +features: [uint8array-base64, TypedArray] +---*/ + +var illegal = [ + 'a.a', + 'aa^', + 'a a', + 'a\ta', + 'a\x0Aa', + 'a\x0Ca', + 'a\x0Da', + 'a\u00A0a', // nbsp + 'a\u2009a', // thin space + 'a\u2028a', // line separator +]; +illegal.forEach(function(value) { + assert.throws(SyntaxError, function() { + var target = new Uint8Array([255, 255, 255, 255, 255]); + target.setFromHex(value); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/length.js new file mode 100644 index 000000000000..b0b56ef76135 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/length.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfromhex +description: > + Uint8Array.prototype.setFromHex.length is 1. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype.setFromHex, 'length', { + value: 1, + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/name.js new file mode 100644 index 000000000000..cbc06e6f3d23 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/name.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfromhex +description: > + Uint8Array.prototype.setFromHex.name is "setFromHex". +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype.setFromHex, 'name', { + value: 'setFromHex', + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js new file mode 100644 index 000000000000..196b962bdf7b --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfromhex +description: > + Uint8Array.prototype.setFromHex is not a constructor function. +includes: [isConstructor.js] +features: [uint8array-base64, TypedArray, Reflect.construct] +---*/ + +assert(!isConstructor(Uint8Array.prototype.setFromHex), "target.setFromHex is not a constructor"); + +assert.throws(TypeError, function() { + var target = new Uint8Array(10); + new target.setFromHex(''); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/results.js new file mode 100644 index 000000000000..c7749c62575b --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/results.js @@ -0,0 +1,34 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfromhex +description: Conversion of hex strings to Uint8Arrays +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +var cases = [ + ["", []], + ["66", [102]], + ["666f", [102, 111]], + ["666F", [102, 111]], + ["666f6f", [102, 111, 111]], + ["666F6f", [102, 111, 111]], + ["666f6f62", [102, 111, 111, 98]], + ["666f6f6261", [102, 111, 111, 98, 97]], + ["666f6f626172", [102, 111, 111, 98, 97, 114]], +]; + +cases.forEach(function (pair) { + var allFF = [255, 255, 255, 255, 255, 255, 255, 255]; + var target = new Uint8Array(allFF); + var result = target.setFromHex(pair[0]); + assert.sameValue(result.read, pair[0].length); + assert.sameValue(result.written, pair[1].length); + + var expected = pair[1].concat(allFF.slice(pair[1].length)) + assert.compareArray(target, expected, "decoding " + pair[0]); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/shell.js new file mode 100644 index 000000000000..a7590326c360 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/shell.js @@ -0,0 +1,42 @@ +// GENERATED, DO NOT EDIT +// file: detachArrayBuffer.js +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + A function used in the process of asserting correctness of TypedArray objects. + + $262.detachArrayBuffer is defined by a host. +defines: [$DETACHBUFFER] +---*/ + +function $DETACHBUFFER(buffer) { + if (!$262 || typeof $262.detachArrayBuffer !== "function") { + throw new Test262Error("No method available to detach an ArrayBuffer"); + } + $262.detachArrayBuffer(buffer); +} + +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js new file mode 100644 index 000000000000..9a6f5f84c022 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js @@ -0,0 +1,24 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfromhex +description: Uint8Array.prototype.setFromHex throws if its first argument is not a string +features: [uint8array-base64, TypedArray] +---*/ + +var toStringCalls = 0; +var throwyToString = { + toString: function() { + toStringCalls += 1; + throw new Test262Error("toString called"); + } +}; + +assert.throws(TypeError, function() { + var target = new Uint8Array(10); + target.setFromHex(throwyToString); +}); +assert.sameValue(toStringCalls, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/subarray.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/subarray.js new file mode 100644 index 000000000000..45879d8cb34a --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/subarray.js @@ -0,0 +1,20 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfromhex +description: Uint8Array.prototype.setFromHex takes into account the offset of the target Uint8Array +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +var base = new Uint8Array([255, 255, 255, 255, 255, 255, 255]); +var subarray = base.subarray(2, 5); + +var result = subarray.setFromHex('aabbcc'); +assert.sameValue(result.read, 6); +assert.sameValue(result.written, 3); +assert.compareArray(subarray, [170, 187, 204]); +assert.compareArray(base, [255, 255, 170, 187, 204, 255, 255]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/target-size.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/target-size.js new file mode 100644 index 000000000000..d73fa1749d25 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/target-size.js @@ -0,0 +1,32 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.setfromhex +description: Uint8Array.prototype.setFromHex behavior when target buffer is small +includes: [compareArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +// buffer too small +var target = new Uint8Array([255, 255]); +var result = target.setFromHex('aabbcc'); +assert.sameValue(result.read, 4); +assert.sameValue(result.written, 2); +assert.compareArray(target, [170, 187]); + +// buffer exact +var target = new Uint8Array([255, 255, 255]); +var result = target.setFromHex('aabbcc'); +assert.sameValue(result.read, 6); +assert.sameValue(result.written, 3); +assert.compareArray(target, [170, 187, 204]); + +// buffer too large +var target = new Uint8Array([255, 255, 255, 255]); +var result = target.setFromHex('aabbcc'); +assert.sameValue(result.read, 6); +assert.sameValue(result.written, 3); +assert.compareArray(target, [170, 187, 204, 255]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/shell.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/alphabet.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/alphabet.js new file mode 100644 index 000000000000..7edf0a379e11 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/alphabet.js @@ -0,0 +1,20 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tobase64 +description: Conversion of Uint8Arrays to base64 strings exercising the alphabet option +features: [uint8array-base64, TypedArray] +---*/ + +assert.sameValue((new Uint8Array([199, 239, 242])).toBase64(), "x+/y"); + +assert.sameValue((new Uint8Array([199, 239, 242])).toBase64({ alphabet: 'base64' }), "x+/y"); + +assert.sameValue((new Uint8Array([199, 239, 242])).toBase64({ alphabet: 'base64url' }), "x-_y"); + +assert.throws(TypeError, function() { + (new Uint8Array([199, 239, 242])).toBase64({ alphabet: 'other' }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/descriptor.js new file mode 100644 index 000000000000..9c34719bf114 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/descriptor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tobase64 +description: > + Uint8Array.prototype.toBase64 has default data property attributes. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype, 'toBase64', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js new file mode 100644 index 000000000000..0904454743bf --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js @@ -0,0 +1,42 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tobase64 +description: Uint8Array.prototype.toBase64 checks for detachedness after side-effects are finished +includes: [detachArrayBuffer.js] +features: [uint8array-base64, TypedArray] +---*/ + +var array = new Uint8Array(2); +var getterCalls = 0; +var receiverDetachingOptions = {}; +Object.defineProperty(receiverDetachingOptions, "alphabet", { + get: function() { + getterCalls += 1; + $DETACHBUFFER(array.buffer); + return "base64"; + } +}); +assert.throws(TypeError, function() { + array.toBase64(receiverDetachingOptions); +}); +assert.sameValue(getterCalls, 1); + + +var detached = new Uint8Array(2); +$DETACHBUFFER(detached.buffer); +var getterCalls = 0; +var sideEffectingOptions = {}; +Object.defineProperty(sideEffectingOptions, "alphabet", { + get: function() { + getterCalls += 1; + return "base64"; + } +}); +assert.throws(TypeError, function() { + detached.toBase64(sideEffectingOptions); +}); +assert.sameValue(getterCalls, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/length.js new file mode 100644 index 000000000000..9e4aabb9ed3c --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/length.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tobase64 +description: > + Uint8Array.prototype.toBase64.length is 0. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype.toBase64, 'length', { + value: 0, + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/name.js new file mode 100644 index 000000000000..2510648b7666 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/name.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tobase64 +description: > + Uint8Array.prototype.toBase64.name is "toBase64". +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype.toBase64, 'name', { + value: 'toBase64', + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js new file mode 100644 index 000000000000..79280e2d5da9 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tobase64 +description: > + Uint8Array.prototype.toBase64 is not a constructor function. +includes: [isConstructor.js] +features: [uint8array-base64, TypedArray, Reflect.construct] +---*/ + +assert(!isConstructor(Uint8Array.prototype.toBase64), "Uint8Array.prototype.toBase64 is not a constructor"); + +var uint8Array = new Uint8Array(8); +assert.throws(TypeError, function() { + new uint8Array.toBase64(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/option-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/option-coercion.js new file mode 100644 index 000000000000..054a3a5e0da0 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/option-coercion.js @@ -0,0 +1,51 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tobase64 +description: Uint8Array.prototype.toBase64 triggers effects of the "alphabet" getter, but does not perform toString on the result +features: [uint8array-base64, TypedArray] +---*/ + +assert.throws(TypeError, function() { + (new Uint8Array(2)).toBase64({ alphabet: Object("base64") }); +}); + + +var toStringCalls = 0; +var throwyToString = { + toString: function() { + toStringCalls += 1; + throw new Test262Error("toString called on alphabet value"); + } +}; +assert.throws(TypeError, function() { + (new Uint8Array(2)).toBase64({ alphabet: throwyToString }); +}); +assert.sameValue(toStringCalls, 0); + +var alphabetAccesses = 0; +var base64UrlOptions = {}; +Object.defineProperty(base64UrlOptions, "alphabet", { + get: function() { + alphabetAccesses += 1; + return "base64url"; + } +}); +assert.sameValue((new Uint8Array([199, 239, 242])).toBase64(base64UrlOptions), "x-_y"); +assert.sameValue(alphabetAccesses, 1); + +// side-effects from the getter on the receiver are reflected in the result +var array = new Uint8Array([0]); +var receiverMutatingOptions = {}; +Object.defineProperty(receiverMutatingOptions, "alphabet", { + get: function() { + array[0] = 255; + return "base64"; + } +}); +var result = array.toBase64(receiverMutatingOptions); +assert.sameValue(result, "/w=="); +assert.sameValue(array[0], 255); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js new file mode 100644 index 000000000000..53352ce4a50e --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js @@ -0,0 +1,36 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tobase64 +description: Uint8Array.prototype.toBase64 throws if the receiver is not a Uint8Array +includes: [testTypedArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +var toBase64 = Uint8Array.prototype.toBase64; + +var options = {}; +Object.defineProperty(options, "alphabet", { + get: function() { + throw new Test262Error("options.alphabet accessed despite incompatible receiver"); + } +}); + +testWithTypedArrayConstructors(function(TA) { + if (TA === Uint8Array) return; + var sample = new TA(2); + assert.throws(TypeError, function() { + Uint8Array.prototype.toBase64.call(sample, options); + }); +}); + +assert.throws(TypeError, function() { + Uint8Array.prototype.toBase64.call([], options); +}); + +assert.throws(TypeError, function() { + toBase64(options); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/results.js new file mode 100644 index 000000000000..5ce75170b7b0 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/results.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tobase64 +description: Conversion of Uint8Arrays to base64 strings +features: [uint8array-base64, TypedArray] +---*/ + +// standard test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10 +assert.sameValue((new Uint8Array([])).toBase64(), ""); +assert.sameValue((new Uint8Array([102])).toBase64(), "Zg=="); +assert.sameValue((new Uint8Array([102, 111])).toBase64(), "Zm8="); +assert.sameValue((new Uint8Array([102, 111, 111])).toBase64(), "Zm9v"); +assert.sameValue((new Uint8Array([102, 111, 111, 98])).toBase64(), "Zm9vYg=="); +assert.sameValue((new Uint8Array([102, 111, 111, 98, 97])).toBase64(), "Zm9vYmE="); +assert.sameValue((new Uint8Array([102, 111, 111, 98, 97, 114])).toBase64(), "Zm9vYmFy"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/shell.js new file mode 100644 index 000000000000..2af708ed5996 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/shell.js @@ -0,0 +1,203 @@ +// GENERATED, DO NOT EDIT +// file: detachArrayBuffer.js +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + A function used in the process of asserting correctness of TypedArray objects. + + $262.detachArrayBuffer is defined by a host. +defines: [$DETACHBUFFER] +---*/ + +function $DETACHBUFFER(buffer) { + if (!$262 || typeof $262.detachArrayBuffer !== "function") { + throw new Test262Error("No method available to detach an ArrayBuffer"); + } + $262.detachArrayBuffer(buffer); +} + +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} + +// file: testTypedArray.js +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Collection of functions used to assert the correctness of TypedArray objects. +defines: + - floatArrayConstructors + - nonClampedIntArrayConstructors + - intArrayConstructors + - typedArrayConstructors + - TypedArray + - testWithTypedArrayConstructors + - nonAtomicsFriendlyTypedArrayConstructors + - testWithAtomicsFriendlyTypedArrayConstructors + - testWithNonAtomicsFriendlyTypedArrayConstructors + - testTypedArrayConversions +---*/ + +var floatArrayConstructors = [ + Float64Array, + Float32Array +]; + +var nonClampedIntArrayConstructors = [ + Int32Array, + Int16Array, + Int8Array, + Uint32Array, + Uint16Array, + Uint8Array +]; + +var intArrayConstructors = nonClampedIntArrayConstructors.concat([Uint8ClampedArray]); + +// Float16Array is a newer feature +// adding it to this list unconditionally would cause implementations lacking it to fail every test which uses it +if (typeof Float16Array !== 'undefined') { + floatArrayConstructors.push(Float16Array); +} + +/** + * Array containing every non-bigint typed array constructor. + */ + +var typedArrayConstructors = floatArrayConstructors.concat(intArrayConstructors); + +/** + * The %TypedArray% intrinsic constructor function. + */ +var TypedArray = Object.getPrototypeOf(Int8Array); + +/** + * Callback for testing a typed array constructor. + * + * @callback typedArrayConstructorCallback + * @param {Function} Constructor the constructor object to test with. + */ + +/** + * Calls the provided function for every typed array constructor. + * + * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor. + * @param {Array} selected - An optional Array with filtered typed arrays + */ +function testWithTypedArrayConstructors(f, selected) { + var constructors = selected || typedArrayConstructors; + for (var i = 0; i < constructors.length; ++i) { + var constructor = constructors[i]; + try { + f(constructor); + } catch (e) { + e.message += " (Testing with " + constructor.name + ".)"; + throw e; + } + } +} + +var nonAtomicsFriendlyTypedArrayConstructors = floatArrayConstructors.concat([Uint8ClampedArray]); +/** + * Calls the provided function for every non-"Atomics Friendly" typed array constructor. + * + * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor. + * @param {Array} selected - An optional Array with filtered typed arrays + */ +function testWithNonAtomicsFriendlyTypedArrayConstructors(f) { + testWithTypedArrayConstructors(f, nonAtomicsFriendlyTypedArrayConstructors); +} + +/** + * Calls the provided function for every "Atomics Friendly" typed array constructor. + * + * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor. + * @param {Array} selected - An optional Array with filtered typed arrays + */ +function testWithAtomicsFriendlyTypedArrayConstructors(f) { + testWithTypedArrayConstructors(f, [ + Int32Array, + Int16Array, + Int8Array, + Uint32Array, + Uint16Array, + Uint8Array, + ]); +} + +/** + * Helper for conversion operations on TypedArrays, the expected values + * properties are indexed in order to match the respective value for each + * TypedArray constructor + * @param {Function} fn - the function to call for each constructor and value. + * will be called with the constructor, value, expected + * value, and a initial value that can be used to avoid + * a false positive with an equivalent expected value. + */ +function testTypedArrayConversions(byteConversionValues, fn) { + var values = byteConversionValues.values; + var expected = byteConversionValues.expected; + + testWithTypedArrayConstructors(function(TA) { + var name = TA.name.slice(0, -5); + + return values.forEach(function(value, index) { + var exp = expected[name][index]; + var initial = 0; + if (exp === 0) { + initial = 1; + } + fn(TA, value, exp, initial); + }); + }); +} + +/** + * Checks if the given argument is one of the float-based TypedArray constructors. + * + * @param {constructor} ctor - the value to check + * @returns {boolean} + */ +function isFloatTypedArrayConstructor(arg) { + return floatArrayConstructors.indexOf(arg) !== -1; +} + +/** + * Determines the precision of the given float-based TypedArray constructor. + * + * @param {constructor} ctor - the value to check + * @returns {string} "half", "single", or "double" for Float16Array, Float32Array, and Float64Array respectively. + */ +function floatTypedArrayConstructorPrecision(FA) { + if (typeof Float16Array !== "undefined" && FA === Float16Array) { + return "half"; + } else if (FA === Float32Array) { + return "single"; + } else if (FA === Float64Array) { + return "double"; + } else { + throw new Error("Malformed test - floatTypedArrayConstructorPrecision called with non-float TypedArray"); + } +} diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/descriptor.js new file mode 100644 index 000000000000..fa1eba15deac --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/descriptor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tohex +description: > + Uint8Array.prototype.toHex has default data property attributes. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype, 'toHex', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/detached-buffer.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/detached-buffer.js new file mode 100644 index 000000000000..e0126f67259c --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/detached-buffer.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tohex +description: Uint8Array.prototype.toHex throws if called on a detached buffer +includes: [detachArrayBuffer.js] +features: [uint8array-base64, TypedArray] +---*/ + +var array = new Uint8Array(2); +$DETACHBUFFER(array.buffer); +assert.throws(TypeError, function() { + array.toHex(); +}); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/length.js new file mode 100644 index 000000000000..9c7d00d69312 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/length.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tohex +description: > + Uint8Array.prototype.toHex.length is 0. +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype.toHex, 'length', { + value: 0, + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/name.js new file mode 100644 index 000000000000..af2e1ef1d4ae --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/name.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tohex +description: > + Uint8Array.prototype.toHex.name is "toHex". +includes: [propertyHelper.js] +features: [uint8array-base64, TypedArray] +---*/ + +verifyProperty(Uint8Array.prototype.toHex, 'name', { + value: 'toHex', + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/nonconstructor.js new file mode 100644 index 000000000000..2d0f9fc00f1a --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/nonconstructor.js @@ -0,0 +1,19 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tohex +description: > + Uint8Array.prototype.toHex is not a constructor function. +includes: [isConstructor.js] +features: [uint8array-base64, TypedArray, Reflect.construct] +---*/ + +assert(!isConstructor(Uint8Array.prototype.toHex), "Uint8Array.prototype.toHex is not a constructor"); + +var uint8Array = new Uint8Array(8); +assert.throws(TypeError, function() { + new uint8Array.toHex(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js new file mode 100644 index 000000000000..1409cca969f0 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js @@ -0,0 +1,29 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tohex +description: Uint8Array.prototype.toHex throws if the receiver is not a Uint8Array +includes: [testTypedArray.js] +features: [uint8array-base64, TypedArray] +---*/ + +var toHex = Uint8Array.prototype.toHex; + +testWithTypedArrayConstructors(function(TA) { + if (TA === Uint8Array) return; + var sample = new TA(2); + assert.throws(TypeError, function() { + Uint8Array.prototype.toHex.call(sample); + }); +}); + +assert.throws(TypeError, function() { + Uint8Array.prototype.toHex.call([]); +}); + +assert.throws(TypeError, function() { + toHex(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/results.js new file mode 100644 index 000000000000..fb8c31096f14 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/results.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-uint8array.prototype.tohex +description: Conversion of Uint8Arrays to hex strings +features: [uint8array-base64, TypedArray] +---*/ + +assert.sameValue((new Uint8Array([])).toHex(), ""); +assert.sameValue((new Uint8Array([102])).toHex(), "66"); +assert.sameValue((new Uint8Array([102, 111])).toHex(), "666f"); +assert.sameValue((new Uint8Array([102, 111, 111])).toHex(), "666f6f"); +assert.sameValue((new Uint8Array([102, 111, 111, 98])).toHex(), "666f6f62"); +assert.sameValue((new Uint8Array([102, 111, 111, 98, 97])).toHex(), "666f6f6261"); +assert.sameValue((new Uint8Array([102, 111, 111, 98, 97, 114])).toHex(), "666f6f626172"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/shell.js new file mode 100644 index 000000000000..2af708ed5996 --- /dev/null +++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/shell.js @@ -0,0 +1,203 @@ +// GENERATED, DO NOT EDIT +// file: detachArrayBuffer.js +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + A function used in the process of asserting correctness of TypedArray objects. + + $262.detachArrayBuffer is defined by a host. +defines: [$DETACHBUFFER] +---*/ + +function $DETACHBUFFER(buffer) { + if (!$262 || typeof $262.detachArrayBuffer !== "function") { + throw new Test262Error("No method available to detach an ArrayBuffer"); + } + $262.detachArrayBuffer(buffer); +} + +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} + +// file: testTypedArray.js +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Collection of functions used to assert the correctness of TypedArray objects. +defines: + - floatArrayConstructors + - nonClampedIntArrayConstructors + - intArrayConstructors + - typedArrayConstructors + - TypedArray + - testWithTypedArrayConstructors + - nonAtomicsFriendlyTypedArrayConstructors + - testWithAtomicsFriendlyTypedArrayConstructors + - testWithNonAtomicsFriendlyTypedArrayConstructors + - testTypedArrayConversions +---*/ + +var floatArrayConstructors = [ + Float64Array, + Float32Array +]; + +var nonClampedIntArrayConstructors = [ + Int32Array, + Int16Array, + Int8Array, + Uint32Array, + Uint16Array, + Uint8Array +]; + +var intArrayConstructors = nonClampedIntArrayConstructors.concat([Uint8ClampedArray]); + +// Float16Array is a newer feature +// adding it to this list unconditionally would cause implementations lacking it to fail every test which uses it +if (typeof Float16Array !== 'undefined') { + floatArrayConstructors.push(Float16Array); +} + +/** + * Array containing every non-bigint typed array constructor. + */ + +var typedArrayConstructors = floatArrayConstructors.concat(intArrayConstructors); + +/** + * The %TypedArray% intrinsic constructor function. + */ +var TypedArray = Object.getPrototypeOf(Int8Array); + +/** + * Callback for testing a typed array constructor. + * + * @callback typedArrayConstructorCallback + * @param {Function} Constructor the constructor object to test with. + */ + +/** + * Calls the provided function for every typed array constructor. + * + * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor. + * @param {Array} selected - An optional Array with filtered typed arrays + */ +function testWithTypedArrayConstructors(f, selected) { + var constructors = selected || typedArrayConstructors; + for (var i = 0; i < constructors.length; ++i) { + var constructor = constructors[i]; + try { + f(constructor); + } catch (e) { + e.message += " (Testing with " + constructor.name + ".)"; + throw e; + } + } +} + +var nonAtomicsFriendlyTypedArrayConstructors = floatArrayConstructors.concat([Uint8ClampedArray]); +/** + * Calls the provided function for every non-"Atomics Friendly" typed array constructor. + * + * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor. + * @param {Array} selected - An optional Array with filtered typed arrays + */ +function testWithNonAtomicsFriendlyTypedArrayConstructors(f) { + testWithTypedArrayConstructors(f, nonAtomicsFriendlyTypedArrayConstructors); +} + +/** + * Calls the provided function for every "Atomics Friendly" typed array constructor. + * + * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor. + * @param {Array} selected - An optional Array with filtered typed arrays + */ +function testWithAtomicsFriendlyTypedArrayConstructors(f) { + testWithTypedArrayConstructors(f, [ + Int32Array, + Int16Array, + Int8Array, + Uint32Array, + Uint16Array, + Uint8Array, + ]); +} + +/** + * Helper for conversion operations on TypedArrays, the expected values + * properties are indexed in order to match the respective value for each + * TypedArray constructor + * @param {Function} fn - the function to call for each constructor and value. + * will be called with the constructor, value, expected + * value, and a initial value that can be used to avoid + * a false positive with an equivalent expected value. + */ +function testTypedArrayConversions(byteConversionValues, fn) { + var values = byteConversionValues.values; + var expected = byteConversionValues.expected; + + testWithTypedArrayConstructors(function(TA) { + var name = TA.name.slice(0, -5); + + return values.forEach(function(value, index) { + var exp = expected[name][index]; + var initial = 0; + if (exp === 0) { + initial = 1; + } + fn(TA, value, exp, initial); + }); + }); +} + +/** + * Checks if the given argument is one of the float-based TypedArray constructors. + * + * @param {constructor} ctor - the value to check + * @returns {boolean} + */ +function isFloatTypedArrayConstructor(arg) { + return floatArrayConstructors.indexOf(arg) !== -1; +} + +/** + * Determines the precision of the given float-based TypedArray constructor. + * + * @param {constructor} ctor - the value to check + * @returns {string} "half", "single", or "double" for Float16Array, Float32Array, and Float64Array respectively. + */ +function floatTypedArrayConstructorPrecision(FA) { + if (typeof Float16Array !== "undefined" && FA === Float16Array) { + return "half"; + } else if (FA === Float32Array) { + return "single"; + } else if (FA === Float64Array) { + return "double"; + } else { + throw new Error("Malformed test - floatTypedArrayConstructorPrecision called with non-float TypedArray"); + } +} diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/shell.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/browser.js b/js/src/tests/test262/prs/3994/built-ins/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/built-ins/shell.js b/js/src/tests/test262/prs/3994/built-ins/shell.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/src/tests/test262/prs/3994/shell.js b/js/src/tests/test262/prs/3994/shell.js new file mode 100644 index 000000000000..9adb7aa9141c --- /dev/null +++ b/js/src/tests/test262/prs/3994/shell.js @@ -0,0 +1,723 @@ +// GENERATED, DO NOT EDIT +// file: assert.js +// Copyright (C) 2017 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Collection of assertion functions used throughout test262 +defines: [assert] +---*/ + + +function assert(mustBeTrue, message) { + if (mustBeTrue === true) { + return; + } + + if (message === undefined) { + message = 'Expected true but got ' + assert._toString(mustBeTrue); + } + throw new Test262Error(message); +} + +assert._isSameValue = function (a, b) { + if (a === b) { + // Handle +/-0 vs. -/+0 + return a !== 0 || 1 / a === 1 / b; + } + + // Handle NaN vs. NaN + return a !== a && b !== b; +}; + +assert.sameValue = function (actual, expected, message) { + try { + if (assert._isSameValue(actual, expected)) { + return; + } + } catch (error) { + throw new Test262Error(message + ' (_isSameValue operation threw) ' + error); + return; + } + + if (message === undefined) { + message = ''; + } else { + message += ' '; + } + + message += 'Expected SameValue(«' + assert._toString(actual) + '», «' + assert._toString(expected) + '») to be true'; + + throw new Test262Error(message); +}; + +assert.notSameValue = function (actual, unexpected, message) { + if (!assert._isSameValue(actual, unexpected)) { + return; + } + + if (message === undefined) { + message = ''; + } else { + message += ' '; + } + + message += 'Expected SameValue(«' + assert._toString(actual) + '», «' + assert._toString(unexpected) + '») to be false'; + + throw new Test262Error(message); +}; + +assert.throws = function (expectedErrorConstructor, func, message) { + var expectedName, actualName; + if (typeof func !== "function") { + throw new Test262Error('assert.throws requires two arguments: the error constructor ' + + 'and a function to run'); + return; + } + if (message === undefined) { + message = ''; + } else { + message += ' '; + } + + try { + func(); + } catch (thrown) { + if (typeof thrown !== 'object' || thrown === null) { + message += 'Thrown value was not an object!'; + throw new Test262Error(message); + } else if (thrown.constructor !== expectedErrorConstructor) { + expectedName = expectedErrorConstructor.name; + actualName = thrown.constructor.name; + if (expectedName === actualName) { + message += 'Expected a ' + expectedName + ' but got a different error constructor with the same name'; + } else { + message += 'Expected a ' + expectedName + ' but got a ' + actualName; + } + throw new Test262Error(message); + } + return; + } + + message += 'Expected a ' + expectedErrorConstructor.name + ' to be thrown but no exception was thrown at all'; + throw new Test262Error(message); +}; + +assert._toString = function (value) { + try { + if (value === 0 && 1 / value === -Infinity) { + return '-0'; + } + + return String(value); + } catch (err) { + if (err.name === 'TypeError') { + return Object.prototype.toString.call(value); + } + + throw err; + } +}; + +// file: compareArray.js +// Copyright (C) 2017 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Compare the contents of two arrays +defines: [compareArray] +---*/ + +function compareArray(a, b) { + if (b.length !== a.length) { + return false; + } + + for (var i = 0; i < a.length; i++) { + if (!compareArray.isSameValue(b[i], a[i])) { + return false; + } + } + return true; +} + +compareArray.isSameValue = function(a, b) { + if (a === 0 && b === 0) return 1 / a === 1 / b; + if (a !== a && b !== b) return true; + + return a === b; +}; + +compareArray.format = function(arrayLike) { + return `[${[].map.call(arrayLike, String).join(', ')}]`; +}; + +assert.compareArray = function(actual, expected, message) { + message = message === undefined ? '' : message; + + if (typeof message === 'symbol') { + message = message.toString(); + } + + assert(actual != null, `First argument shouldn't be nullish. ${message}`); + assert(expected != null, `Second argument shouldn't be nullish. ${message}`); + var format = compareArray.format; + var result = compareArray(actual, expected); + + // The following prevents actual and expected from being iterated and evaluated + // more than once unless absolutely necessary. + if (!result) { + assert(false, `Expected ${format(actual)} and ${format(expected)} to have the same contents. ${message}`); + } +}; + +// file: propertyHelper.js +// Copyright (C) 2017 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Collection of functions used to safely verify the correctness of + property descriptors. +defines: + - verifyProperty + - verifyEqualTo # deprecated + - verifyWritable # deprecated + - verifyNotWritable # deprecated + - verifyEnumerable # deprecated + - verifyNotEnumerable # deprecated + - verifyConfigurable # deprecated + - verifyNotConfigurable # deprecated +---*/ + +// @ts-check + +/** + * @param {object} obj + * @param {string|symbol} name + * @param {PropertyDescriptor|undefined} desc + * @param {object} [options] + * @param {boolean} [options.restore] + */ +function verifyProperty(obj, name, desc, options) { + assert( + arguments.length > 2, + 'verifyProperty should receive at least 3 arguments: obj, name, and descriptor' + ); + + var originalDesc = Object.getOwnPropertyDescriptor(obj, name); + var nameStr = String(name); + + // Allows checking for undefined descriptor if it's explicitly given. + if (desc === undefined) { + assert.sameValue( + originalDesc, + undefined, + "obj['" + nameStr + "'] descriptor should be undefined" + ); + + // desc and originalDesc are both undefined, problem solved; + return true; + } + + assert( + Object.prototype.hasOwnProperty.call(obj, name), + "obj should have an own property " + nameStr + ); + + assert.notSameValue( + desc, + null, + "The desc argument should be an object or undefined, null" + ); + + assert.sameValue( + typeof desc, + "object", + "The desc argument should be an object or undefined, " + String(desc) + ); + + var names = Object.getOwnPropertyNames(desc); + for (var i = 0; i < names.length; i++) { + assert( + names[i] === "value" || + names[i] === "writable" || + names[i] === "enumerable" || + names[i] === "configurable" || + names[i] === "get" || + names[i] === "set", + "Invalid descriptor field: " + names[i], + ); + } + + var failures = []; + + if (Object.prototype.hasOwnProperty.call(desc, 'value')) { + if (!isSameValue(desc.value, originalDesc.value)) { + failures.push("descriptor value should be " + desc.value); + } + if (!isSameValue(desc.value, obj[name])) { + failures.push("object value should be " + desc.value); + } + } + + if (Object.prototype.hasOwnProperty.call(desc, 'enumerable')) { + if (desc.enumerable !== originalDesc.enumerable || + desc.enumerable !== isEnumerable(obj, name)) { + failures.push('descriptor should ' + (desc.enumerable ? '' : 'not ') + 'be enumerable'); + } + } + + if (Object.prototype.hasOwnProperty.call(desc, 'writable')) { + if (desc.writable !== originalDesc.writable || + desc.writable !== isWritable(obj, name)) { + failures.push('descriptor should ' + (desc.writable ? '' : 'not ') + 'be writable'); + } + } + + if (Object.prototype.hasOwnProperty.call(desc, 'configurable')) { + if (desc.configurable !== originalDesc.configurable || + desc.configurable !== isConfigurable(obj, name)) { + failures.push('descriptor should ' + (desc.configurable ? '' : 'not ') + 'be configurable'); + } + } + + assert(!failures.length, failures.join('; ')); + + if (options && options.restore) { + Object.defineProperty(obj, name, originalDesc); + } + + return true; +} + +function isConfigurable(obj, name) { + var hasOwnProperty = Object.prototype.hasOwnProperty; + try { + delete obj[name]; + } catch (e) { + if (!(e instanceof TypeError)) { + throw new Test262Error("Expected TypeError, got " + e); + } + } + return !hasOwnProperty.call(obj, name); +} + +function isEnumerable(obj, name) { + var stringCheck = false; + + if (typeof name === "string") { + for (var x in obj) { + if (x === name) { + stringCheck = true; + break; + } + } + } else { + // skip it if name is not string, works for Symbol names. + stringCheck = true; + } + + return stringCheck && + Object.prototype.hasOwnProperty.call(obj, name) && + Object.prototype.propertyIsEnumerable.call(obj, name); +} + +function isSameValue(a, b) { + if (a === 0 && b === 0) return 1 / a === 1 / b; + if (a !== a && b !== b) return true; + + return a === b; +} + +var __isArray = Array.isArray; +function isWritable(obj, name, verifyProp, value) { + var unlikelyValue = __isArray(obj) && name === "length" ? + Math.pow(2, 32) - 1 : + "unlikelyValue"; + var newValue = value || unlikelyValue; + var hadValue = Object.prototype.hasOwnProperty.call(obj, name); + var oldValue = obj[name]; + var writeSucceeded; + + try { + obj[name] = newValue; + } catch (e) { + if (!(e instanceof TypeError)) { + throw new Test262Error("Expected TypeError, got " + e); + } + } + + writeSucceeded = isSameValue(obj[verifyProp || name], newValue); + + // Revert the change only if it was successful (in other cases, reverting + // is unnecessary and may trigger exceptions for certain property + // configurations) + if (writeSucceeded) { + if (hadValue) { + obj[name] = oldValue; + } else { + delete obj[name]; + } + } + + return writeSucceeded; +} + +/** + * Deprecated; please use `verifyProperty` in new tests. + */ +function verifyEqualTo(obj, name, value) { + if (!isSameValue(obj[name], value)) { + throw new Test262Error("Expected obj[" + String(name) + "] to equal " + value + + ", actually " + obj[name]); + } +} + +/** + * Deprecated; please use `verifyProperty` in new tests. + */ +function verifyWritable(obj, name, verifyProp, value) { + if (!verifyProp) { + assert(Object.getOwnPropertyDescriptor(obj, name).writable, + "Expected obj[" + String(name) + "] to have writable:true."); + } + if (!isWritable(obj, name, verifyProp, value)) { + throw new Test262Error("Expected obj[" + String(name) + "] to be writable, but was not."); + } +} + +/** + * Deprecated; please use `verifyProperty` in new tests. + */ +function verifyNotWritable(obj, name, verifyProp, value) { + if (!verifyProp) { + assert(!Object.getOwnPropertyDescriptor(obj, name).writable, + "Expected obj[" + String(name) + "] to have writable:false."); + } + if (isWritable(obj, name, verifyProp)) { + throw new Test262Error("Expected obj[" + String(name) + "] NOT to be writable, but was."); + } +} + +/** + * Deprecated; please use `verifyProperty` in new tests. + */ +function verifyEnumerable(obj, name) { + assert(Object.getOwnPropertyDescriptor(obj, name).enumerable, + "Expected obj[" + String(name) + "] to have enumerable:true."); + if (!isEnumerable(obj, name)) { + throw new Test262Error("Expected obj[" + String(name) + "] to be enumerable, but was not."); + } +} + +/** + * Deprecated; please use `verifyProperty` in new tests. + */ +function verifyNotEnumerable(obj, name) { + assert(!Object.getOwnPropertyDescriptor(obj, name).enumerable, + "Expected obj[" + String(name) + "] to have enumerable:false."); + if (isEnumerable(obj, name)) { + throw new Test262Error("Expected obj[" + String(name) + "] NOT to be enumerable, but was."); + } +} + +/** + * Deprecated; please use `verifyProperty` in new tests. + */ +function verifyConfigurable(obj, name) { + assert(Object.getOwnPropertyDescriptor(obj, name).configurable, + "Expected obj[" + String(name) + "] to have configurable:true."); + if (!isConfigurable(obj, name)) { + throw new Test262Error("Expected obj[" + String(name) + "] to be configurable, but was not."); + } +} + +/** + * Deprecated; please use `verifyProperty` in new tests. + */ +function verifyNotConfigurable(obj, name) { + assert(!Object.getOwnPropertyDescriptor(obj, name).configurable, + "Expected obj[" + String(name) + "] to have configurable:false."); + if (isConfigurable(obj, name)) { + throw new Test262Error("Expected obj[" + String(name) + "] NOT to be configurable, but was."); + } +} + +// file: sta.js +// Copyright (c) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Provides both: + + - An error class to avoid false positives when testing for thrown exceptions + - A function to explicitly throw an exception using the Test262Error class +defines: [Test262Error, $DONOTEVALUATE] +---*/ + + +function Test262Error(message) { + this.message = message || ""; +} + +Test262Error.prototype.toString = function () { + return "Test262Error: " + this.message; +}; + +Test262Error.thrower = function (message) { + throw new Test262Error(message); +}; + +function $DONOTEVALUATE() { + throw "Test262: This statement should not be evaluated."; +} + +// file: test262-host.js +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// https://github.com/tc39/test262/blob/main/INTERPRETING.md#host-defined-functions +;(function createHostObject(global) { + "use strict"; + + // Save built-in functions and constructors. + var FunctionToString = global.Function.prototype.toString; + var ReflectApply = global.Reflect.apply; + var Atomics = global.Atomics; + var Error = global.Error; + var SharedArrayBuffer = global.SharedArrayBuffer; + var Int32Array = global.Int32Array; + + // Save built-in shell functions. + var NewGlobal = global.newGlobal; + var setSharedArrayBuffer = global.setSharedArrayBuffer; + var getSharedArrayBuffer = global.getSharedArrayBuffer; + var evalInWorker = global.evalInWorker; + var monotonicNow = global.monotonicNow; + var gc = global.gc; + var clearKeptObjects = global.clearKeptObjects; + + var hasCreateIsHTMLDDA = "createIsHTMLDDA" in global; + var hasThreads = ("helperThreadCount" in global ? global.helperThreadCount() > 0 : true); + var hasMailbox = typeof setSharedArrayBuffer === "function" && typeof getSharedArrayBuffer === "function"; + var hasEvalInWorker = typeof evalInWorker === "function"; + + if (!hasCreateIsHTMLDDA && !("document" in global && "all" in global.document)) + throw new Error("no [[IsHTMLDDA]] object available for testing"); + + var IsHTMLDDA = hasCreateIsHTMLDDA + ? global.createIsHTMLDDA() + : global.document.all; + + // The $262.agent framework is not appropriate for browsers yet, and some + // test cases can't work in browsers (they block the main thread). + + var shellCode = hasMailbox && hasEvalInWorker; + var sabTestable = Atomics && SharedArrayBuffer && hasThreads && shellCode; + + global.$262 = { + __proto__: null, + createRealm() { + var newGlobalObject = NewGlobal(); + var createHostObjectFn = ReflectApply(FunctionToString, createHostObject, []); + newGlobalObject.Function(`${createHostObjectFn} createHostObject(this);`)(); + return newGlobalObject.$262; + }, + detachArrayBuffer: global.detachArrayBuffer, + evalScript: global.evaluateScript || global.evaluate, + global, + IsHTMLDDA, + gc() { + gc(); + }, + clearKeptObjects() { + clearKeptObjects(); + }, + agent: (function () { + + // SpiderMonkey complication: With run-time argument --no-threads + // our test runner will not properly filter test cases that can't be + // run because agents can't be started, and so we do a little + // filtering here: We will quietly succeed and exit if an agent test + // should not have been run because threads cannot be started. + // + // Firefox complication: The test cases that use $262.agent can't + // currently work in the browser, so for now we rely on them not + // being run at all. + + if (!sabTestable) { + let {reportCompare, quit} = global; + + function notAvailable() { + // See comment above. + if (!hasThreads && shellCode) { + reportCompare(0, 0); + quit(0); + } + throw new Error("Agents not available"); + } + + return { + start(script) { notAvailable() }, + broadcast(sab, id) { notAvailable() }, + getReport() { notAvailable() }, + sleep(s) { notAvailable() }, + monotonicNow, + } + } + + // The SpiderMonkey implementation uses a designated shared buffer _ia + // for coordination, and spinlocks for everything except sleeping. + + var _MSG_LOC = 0; // Low bit set: broadcast available; High bits: seq # + var _ID_LOC = 1; // ID sent with broadcast + var _ACK_LOC = 2; // Worker increments this to ack that broadcast was received + var _RDY_LOC = 3; // Worker increments this to ack that worker is up and running + var _LOCKTXT_LOC = 4; // Writer lock for the text buffer: 0=open, 1=closed + var _NUMTXT_LOC = 5; // Count of messages in text buffer + var _NEXT_LOC = 6; // First free location in the buffer + var _SLEEP_LOC = 7; // Used for sleeping + + var _FIRST = 10; // First location of first message + + var _ia = new Int32Array(new SharedArrayBuffer(65536)); + _ia[_NEXT_LOC] = _FIRST; + + var _worker_prefix = +// BEGIN WORKER PREFIX +`if (typeof $262 === 'undefined') + $262 = {}; +$262.agent = (function (global) { + var ReflectApply = global.Reflect.apply; + var StringCharCodeAt = global.String.prototype.charCodeAt; + var { + add: Atomics_add, + compareExchange: Atomics_compareExchange, + load: Atomics_load, + store: Atomics_store, + wait: Atomics_wait, + } = global.Atomics; + + var {getSharedArrayBuffer} = global; + + var _ia = new Int32Array(getSharedArrayBuffer()); + var agent = { + receiveBroadcast(receiver) { + var k; + while (((k = Atomics_load(_ia, ${_MSG_LOC})) & 1) === 0) + ; + var received_sab = getSharedArrayBuffer(); + var received_id = Atomics_load(_ia, ${_ID_LOC}); + Atomics_add(_ia, ${_ACK_LOC}, 1); + while (Atomics_load(_ia, ${_MSG_LOC}) === k) + ; + receiver(received_sab, received_id); + }, + + report(msg) { + while (Atomics_compareExchange(_ia, ${_LOCKTXT_LOC}, 0, 1) === 1) + ; + msg = "" + msg; + var i = _ia[${_NEXT_LOC}]; + _ia[i++] = msg.length; + for ( let j=0 ; j < msg.length ; j++ ) + _ia[i++] = ReflectApply(StringCharCodeAt, msg, [j]); + _ia[${_NEXT_LOC}] = i; + Atomics_add(_ia, ${_NUMTXT_LOC}, 1); + Atomics_store(_ia, ${_LOCKTXT_LOC}, 0); + }, + + sleep(s) { + Atomics_wait(_ia, ${_SLEEP_LOC}, 0, s); + }, + + leaving() {}, + + monotonicNow: global.monotonicNow, + }; + Atomics_add(_ia, ${_RDY_LOC}, 1); + return agent; +})(this);`; +// END WORKER PREFIX + + var _numWorkers = 0; + var _numReports = 0; + var _reportPtr = _FIRST; + var { + add: Atomics_add, + load: Atomics_load, + store: Atomics_store, + wait: Atomics_wait, + } = Atomics; + var StringFromCharCode = global.String.fromCharCode; + + return { + start(script) { + setSharedArrayBuffer(_ia.buffer); + var oldrdy = Atomics_load(_ia, _RDY_LOC); + evalInWorker(_worker_prefix + script); + while (Atomics_load(_ia, _RDY_LOC) === oldrdy) + ; + _numWorkers++; + }, + + broadcast(sab, id) { + setSharedArrayBuffer(sab); + Atomics_store(_ia, _ID_LOC, id); + Atomics_store(_ia, _ACK_LOC, 0); + Atomics_add(_ia, _MSG_LOC, 1); + while (Atomics_load(_ia, _ACK_LOC) < _numWorkers) + ; + Atomics_add(_ia, _MSG_LOC, 1); + }, + + getReport() { + if (_numReports === Atomics_load(_ia, _NUMTXT_LOC)) + return null; + var s = ""; + var i = _reportPtr; + var len = _ia[i++]; + for ( let j=0 ; j < len ; j++ ) + s += StringFromCharCode(_ia[i++]); + _reportPtr = i; + _numReports++; + return s; + }, + + sleep(s) { + Atomics_wait(_ia, _SLEEP_LOC, 0, s); + }, + + monotonicNow, + }; + })() + }; +})(this); + +var $mozAsyncTestDone = false; +function $DONE(failure) { + // This function is generally called from within a Promise handler, so any + // exception thrown by this method will be swallowed and most likely + // ignored by the Promise machinery. + if ($mozAsyncTestDone) { + reportFailure("$DONE() already called"); + return; + } + $mozAsyncTestDone = true; + + if (failure) + reportFailure(failure); + else + reportCompare(0, 0); + + if (typeof jsTestDriverEnd === "function") { + gDelayTestDriverEnd = false; + jsTestDriverEnd(); + } +} + +// Some tests in test262 leave promise rejections unhandled. +if ("ignoreUnhandledRejections" in this) { + ignoreUnhandledRejections(); +} -- 2.11.4.GIT