diff --git a/features.txt b/features.txt index 1a43df40dd..51e88dbd5b 100644 --- a/features.txt +++ b/features.txt @@ -131,6 +131,10 @@ source-phase-imports ## test262 special specifier source-phase-imports-module-source +# Uint8Array Base64 +# https://github.com/tc39/proposal-arraybuffer-base64 +uint8array-base64 + ## Standard language features # # Language features that have been included in a published version of the diff --git a/test/built-ins/Uint8Array/fromBase64/alphabet.js b/test/built-ins/Uint8Array/fromBase64/alphabet.js new file mode 100644 index 0000000000..4abc429db5 --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/alphabet.js @@ -0,0 +1,22 @@ +// 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' }); +}); diff --git a/test/built-ins/Uint8Array/fromBase64/descriptor.js b/test/built-ins/Uint8Array/fromBase64/descriptor.js new file mode 100644 index 0000000000..a39b51cd82 --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/descriptor.js @@ -0,0 +1,15 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/fromBase64/ignores-receiver.js b/test/built-ins/Uint8Array/fromBase64/ignores-receiver.js new file mode 100644 index 0000000000..62aa60a3c3 --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/ignores-receiver.js @@ -0,0 +1,19 @@ +// 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); diff --git a/test/built-ins/Uint8Array/fromBase64/illegal-characters.js b/test/built-ins/Uint8Array/fromBase64/illegal-characters.js new file mode 100644 index 0000000000..be3b66b020 --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/illegal-characters.js @@ -0,0 +1,23 @@ +// 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) + }); +}); diff --git a/test/built-ins/Uint8Array/fromBase64/last-chunk-handling.js b/test/built-ins/Uint8Array/fromBase64/last-chunk-handling.js new file mode 100644 index 0000000000..80d3f1654e --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/last-chunk-handling.js @@ -0,0 +1,64 @@ +// 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' }); +}); diff --git a/test/built-ins/Uint8Array/fromBase64/length.js b/test/built-ins/Uint8Array/fromBase64/length.js new file mode 100644 index 0000000000..d251d7754f --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/length.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/fromBase64/name.js b/test/built-ins/Uint8Array/fromBase64/name.js new file mode 100644 index 0000000000..71ed9a3b7d --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/name.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/fromBase64/nonconstructor.js b/test/built-ins/Uint8Array/fromBase64/nonconstructor.js new file mode 100644 index 0000000000..469e00400f --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/nonconstructor.js @@ -0,0 +1,15 @@ +// 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(''); +}); diff --git a/test/built-ins/Uint8Array/fromBase64/option-coercion.js b/test/built-ins/Uint8Array/fromBase64/option-coercion.js new file mode 100644 index 0000000000..5a3a98a714 --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/option-coercion.js @@ -0,0 +1,59 @@ +// 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); diff --git a/test/built-ins/Uint8Array/fromBase64/results.js b/test/built-ins/Uint8Array/fromBase64/results.js new file mode 100644 index 0000000000..cf98d0808a --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/results.js @@ -0,0 +1,27 @@ +// 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]); +}); diff --git a/test/built-ins/Uint8Array/fromBase64/string-coercion.js b/test/built-ins/Uint8Array/fromBase64/string-coercion.js new file mode 100644 index 0000000000..da52fd5403 --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/string-coercion.js @@ -0,0 +1,41 @@ +// 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); diff --git a/test/built-ins/Uint8Array/fromBase64/whitespace.js b/test/built-ins/Uint8Array/fromBase64/whitespace.js new file mode 100644 index 0000000000..bf7d104e3d --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/whitespace.js @@ -0,0 +1,22 @@ +// 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]); +}); diff --git a/test/built-ins/Uint8Array/fromHex/descriptor.js b/test/built-ins/Uint8Array/fromHex/descriptor.js new file mode 100644 index 0000000000..44fdd904e1 --- /dev/null +++ b/test/built-ins/Uint8Array/fromHex/descriptor.js @@ -0,0 +1,15 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/fromHex/ignores-receiver.js b/test/built-ins/Uint8Array/fromHex/ignores-receiver.js new file mode 100644 index 0000000000..2b96a67493 --- /dev/null +++ b/test/built-ins/Uint8Array/fromHex/ignores-receiver.js @@ -0,0 +1,19 @@ +// 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); diff --git a/test/built-ins/Uint8Array/fromHex/illegal-characters.js b/test/built-ins/Uint8Array/fromHex/illegal-characters.js new file mode 100644 index 0000000000..4b870a7b0a --- /dev/null +++ b/test/built-ins/Uint8Array/fromHex/illegal-characters.js @@ -0,0 +1,25 @@ +// 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) + }); +}); diff --git a/test/built-ins/Uint8Array/fromHex/length.js b/test/built-ins/Uint8Array/fromHex/length.js new file mode 100644 index 0000000000..0f52a22f3e --- /dev/null +++ b/test/built-ins/Uint8Array/fromHex/length.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/fromHex/name.js b/test/built-ins/Uint8Array/fromHex/name.js new file mode 100644 index 0000000000..6397c3bd33 --- /dev/null +++ b/test/built-ins/Uint8Array/fromHex/name.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/fromHex/nonconstructor.js b/test/built-ins/Uint8Array/fromHex/nonconstructor.js new file mode 100644 index 0000000000..ca3b52a834 --- /dev/null +++ b/test/built-ins/Uint8Array/fromHex/nonconstructor.js @@ -0,0 +1,15 @@ +// 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(''); +}); diff --git a/test/built-ins/Uint8Array/fromHex/odd-length-input.js b/test/built-ins/Uint8Array/fromHex/odd-length-input.js new file mode 100644 index 0000000000..9097fb700f --- /dev/null +++ b/test/built-ins/Uint8Array/fromHex/odd-length-input.js @@ -0,0 +1,11 @@ +// 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'); +}); diff --git a/test/built-ins/Uint8Array/fromHex/results.js b/test/built-ins/Uint8Array/fromHex/results.js new file mode 100644 index 0000000000..c4bf09dd33 --- /dev/null +++ b/test/built-ins/Uint8Array/fromHex/results.js @@ -0,0 +1,28 @@ +// 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]); +}); diff --git a/test/built-ins/Uint8Array/fromHex/string-coercion.js b/test/built-ins/Uint8Array/fromHex/string-coercion.js new file mode 100644 index 0000000000..fd6efcc0f0 --- /dev/null +++ b/test/built-ins/Uint8Array/fromHex/string-coercion.js @@ -0,0 +1,20 @@ +// 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); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js b/test/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js new file mode 100644 index 0000000000..ec33eaf6c9 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js @@ -0,0 +1,41 @@ +// 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' }); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js b/test/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js new file mode 100644 index 0000000000..3bfc1a4ecd --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js @@ -0,0 +1,15 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js b/test/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js new file mode 100644 index 0000000000..50c65c4e5b --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js @@ -0,0 +1,29 @@ +// 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); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js b/test/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js new file mode 100644 index 0000000000..3d22adddca --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js @@ -0,0 +1,24 @@ +// 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); + }); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js b/test/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js new file mode 100644 index 0000000000..9142633a58 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js @@ -0,0 +1,153 @@ +// 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' }); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/length.js b/test/built-ins/Uint8Array/prototype/setFromBase64/length.js new file mode 100644 index 0000000000..23fe10c352 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/length.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/name.js b/test/built-ins/Uint8Array/prototype/setFromBase64/name.js new file mode 100644 index 0000000000..a80e8ffb3f --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/name.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js b/test/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js new file mode 100644 index 0000000000..e2344f2d26 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js @@ -0,0 +1,16 @@ +// 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(''); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js b/test/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js new file mode 100644 index 0000000000..bf54e4d073 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js @@ -0,0 +1,69 @@ +// 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); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/results.js b/test/built-ins/Uint8Array/prototype/setFromBase64/results.js new file mode 100644 index 0000000000..016c6a34fd --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/results.js @@ -0,0 +1,30 @@ +// 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]); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js b/test/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js new file mode 100644 index 0000000000..eb1be0aac8 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js @@ -0,0 +1,43 @@ +// 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); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/subarray.js b/test/built-ins/Uint8Array/prototype/setFromBase64/subarray.js new file mode 100644 index 0000000000..98cea3aaf3 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/subarray.js @@ -0,0 +1,17 @@ +// 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]); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/target-size.js b/test/built-ins/Uint8Array/prototype/setFromBase64/target-size.js new file mode 100644 index 0000000000..7566d8122e --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/target-size.js @@ -0,0 +1,64 @@ +// 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]); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js b/test/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js new file mode 100644 index 0000000000..733970884c --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js @@ -0,0 +1,23 @@ +// 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]); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/descriptor.js b/test/built-ins/Uint8Array/prototype/setFromHex/descriptor.js new file mode 100644 index 0000000000..8d5e4f3321 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/descriptor.js @@ -0,0 +1,15 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js b/test/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js new file mode 100644 index 0000000000..ccfc9f1031 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js @@ -0,0 +1,14 @@ +// 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'); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js b/test/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js new file mode 100644 index 0000000000..f8c8dbdb00 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js @@ -0,0 +1,26 @@ +// 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); + }); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/length.js b/test/built-ins/Uint8Array/prototype/setFromHex/length.js new file mode 100644 index 0000000000..479d0f12d8 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/length.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/name.js b/test/built-ins/Uint8Array/prototype/setFromHex/name.js new file mode 100644 index 0000000000..9967d38ee2 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/name.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js b/test/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js new file mode 100644 index 0000000000..4af1330391 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js @@ -0,0 +1,16 @@ +// 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(''); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/results.js b/test/built-ins/Uint8Array/prototype/setFromHex/results.js new file mode 100644 index 0000000000..870d49656d --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/results.js @@ -0,0 +1,31 @@ +// 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]); +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js b/test/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js new file mode 100644 index 0000000000..5e877b3d0b --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js @@ -0,0 +1,21 @@ +// 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); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/subarray.js b/test/built-ins/Uint8Array/prototype/setFromHex/subarray.js new file mode 100644 index 0000000000..72a33b6daf --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/subarray.js @@ -0,0 +1,17 @@ +// 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]); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/target-size.js b/test/built-ins/Uint8Array/prototype/setFromHex/target-size.js new file mode 100644 index 0000000000..f3aed06f25 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/target-size.js @@ -0,0 +1,29 @@ +// 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]); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/alphabet.js b/test/built-ins/Uint8Array/prototype/toBase64/alphabet.js new file mode 100644 index 0000000000..a20b3c1446 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toBase64/alphabet.js @@ -0,0 +1,17 @@ +// 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' }); +}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/descriptor.js b/test/built-ins/Uint8Array/prototype/toBase64/descriptor.js new file mode 100644 index 0000000000..52ba4ecad1 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toBase64/descriptor.js @@ -0,0 +1,15 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js b/test/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js new file mode 100644 index 0000000000..b8b1c2999a --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js @@ -0,0 +1,39 @@ +// 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); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/length.js b/test/built-ins/Uint8Array/prototype/toBase64/length.js new file mode 100644 index 0000000000..8f08a29156 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toBase64/length.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/name.js b/test/built-ins/Uint8Array/prototype/toBase64/name.js new file mode 100644 index 0000000000..71cd95403c --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toBase64/name.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js b/test/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js new file mode 100644 index 0000000000..9b07eb2660 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js @@ -0,0 +1,16 @@ +// 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(); +}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/option-coercion.js b/test/built-ins/Uint8Array/prototype/toBase64/option-coercion.js new file mode 100644 index 0000000000..4cd9615272 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toBase64/option-coercion.js @@ -0,0 +1,48 @@ +// 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); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js b/test/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js new file mode 100644 index 0000000000..0ade97bad2 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js @@ -0,0 +1,33 @@ +// 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); +}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/results.js b/test/built-ins/Uint8Array/prototype/toBase64/results.js new file mode 100644 index 0000000000..88d2ba111f --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toBase64/results.js @@ -0,0 +1,16 @@ +// 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"); diff --git a/test/built-ins/Uint8Array/prototype/toHex/descriptor.js b/test/built-ins/Uint8Array/prototype/toHex/descriptor.js new file mode 100644 index 0000000000..c70b782539 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toHex/descriptor.js @@ -0,0 +1,15 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/toHex/detached-buffer.js b/test/built-ins/Uint8Array/prototype/toHex/detached-buffer.js new file mode 100644 index 0000000000..016d2c8ed4 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toHex/detached-buffer.js @@ -0,0 +1,15 @@ +// 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(); +}); + diff --git a/test/built-ins/Uint8Array/prototype/toHex/length.js b/test/built-ins/Uint8Array/prototype/toHex/length.js new file mode 100644 index 0000000000..6bc061be01 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toHex/length.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/toHex/name.js b/test/built-ins/Uint8Array/prototype/toHex/name.js new file mode 100644 index 0000000000..8cfa952873 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toHex/name.js @@ -0,0 +1,16 @@ +// 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 +}); diff --git a/test/built-ins/Uint8Array/prototype/toHex/nonconstructor.js b/test/built-ins/Uint8Array/prototype/toHex/nonconstructor.js new file mode 100644 index 0000000000..bb3d9e155a --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toHex/nonconstructor.js @@ -0,0 +1,16 @@ +// 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(); +}); diff --git a/test/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js b/test/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js new file mode 100644 index 0000000000..42ac67ec97 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js @@ -0,0 +1,26 @@ +// 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(); +}); diff --git a/test/built-ins/Uint8Array/prototype/toHex/results.js b/test/built-ins/Uint8Array/prototype/toHex/results.js new file mode 100644 index 0000000000..8d0bcf4310 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toHex/results.js @@ -0,0 +1,15 @@ +// 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");