tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit ecc3c84c8a5601edd4e675823bd06bbff7a528ed
parent 50c434493d69d727412bb7c7062b9744d5cfaeca
Author: Sandor Molnar <smolnar@mozilla.com>
Date:   Wed, 29 Oct 2025 13:30:08 +0200

Revert "Bug 1996770: Align memory before reinterpreting as uint32. r=iain" for causing jsreftest failures

This reverts commit 5c24f7dba833e96b28ecd6f00587e6aff19daeea.

Diffstat:
Djs/src/tests/non262/TypedArray/base64-and-hex-unaligned-buffer.js | 85-------------------------------------------------------------------------------
Mjs/src/vm/TypedArrayObject.cpp | 65+++++++++--------------------------------------------------------
2 files changed, 9 insertions(+), 141 deletions(-)

diff --git a/js/src/tests/non262/TypedArray/base64-and-hex-unaligned-buffer.js b/js/src/tests/non262/TypedArray/base64-and-hex-unaligned-buffer.js @@ -1,85 +0,0 @@ -function toBase64(Buffer) { - for (var length = 1; length <= 32; ++length) { - var buffer = new Buffer(length); - for (var offset = 0; offset < length; ++offset) { - var u8 = new Uint8Array(buffer, offset); - assertEq(u8.length > 0, true); - - var str = u8.toBase64(); - assertEq(str.startsWith("A"), true); - assertEq(str.endsWith("A") || str.endsWith("="), true); - } - } -} -toBase64(ArrayBuffer); -if (typeof SharedArrayBuffer === "function"); - toBase64(SharedArrayBuffer); - -function toHex(Buffer) { - for (var length = 1; length <= 32; ++length) { - var buffer = new Buffer(length); - for (var offset = 0; offset < length; ++offset) { - var u8 = new Uint8Array(buffer, offset); - assertEq(u8.length > 0, true); - - var str = u8.toHex(); - assertEq(str.startsWith("00"), true); - assertEq(str.endsWith("00"), true); - } - } -} -toHex(ArrayBuffer); -if (typeof SharedArrayBuffer === "function"); - toHex(SharedArrayBuffer); - -function setFromHex(Buffer) { - var input = "aabbccddeeff00112233445566778899"; - - for (var length = 1; length <= 32; ++length) { - var buffer = new Buffer(length); - for (var offset = 0; offset < length; ++offset) { - var u8 = new Uint8Array(buffer, offset); - assertEq(u8.length > 0, true); - - for (var str = input; str.length; str = str.slice(0, -2)) { - u8.setFromHex(str); - assertEq(u8[0], 0xaa); - } - } - } -} -setFromHex(ArrayBuffer); -if (typeof SharedArrayBuffer === "function"); - setFromHex(SharedArrayBuffer); - -function setFromBase64(Buffer) { - var input = "AAA".repeat(16); - - for (var length = 1; length <= 32; ++length) { - var buffer = new Buffer(length); - for (var offset = 0; offset < length; ++offset) { - var u8 = new Uint8Array(buffer, offset); - assertEq(u8.length > 0, true); - - for (var str = input; str.length; str = str.slice(0, -4)) { - u8.setFromBase64(str); - assertEq(u8[0], 0); - - u8.setFromBase64(str.slice(0, -1) + "="); - assertEq(u8[0], 0); - - u8.setFromBase64(str.slice(0, -2) + "=="); - assertEq(u8[0], 0); - - u8.setFromBase64(str.slice(0, -3), {lastChunkHandling: "stop-before-partial"}); - assertEq(u8[0], 0); - } - } - } -} -setFromBase64(ArrayBuffer); -if (typeof SharedArrayBuffer === "function"); - setFromBase64(SharedArrayBuffer); - -if (typeof reportCompare === "function") - reportCompare(true, true); diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp @@ -4380,10 +4380,6 @@ static size_t FromHex(const CharT* chars, size_t length, } }; - auto decode2Chars = [&](const CharT* chars) { - return (decodeChar(chars[0]) << 4) | (decodeChar(chars[1]) << 0); - }; - auto decode4Chars = [&](const CharT* chars) { return (decodeChar(chars[2]) << 12) | (decodeChar(chars[3]) << 8) | (decodeChar(chars[0]) << 4) | (decodeChar(chars[1]) << 0); @@ -4396,34 +4392,12 @@ static size_t FromHex(const CharT* chars, size_t length, MOZ_ASSERT(length % 2 == 0); // Process eight characters per loop iteration. - if (length >= 8) { - // Align |data| to uint32_t. - if (MOZ_UNLIKELY(data.unwrapValue() & 3)) { - // Performs at most three iterations until |data| is aligned, reading up - // to six characters. - while (data.unwrapValue() & 3) { - // Step 6.a and 6.d. - uint32_t byte = decode2Chars(chars + index); - - // Step 6.b. - if (MOZ_UNLIKELY(int32_t(byte) < 0)) { - return index; - } - MOZ_ASSERT(byte <= 0xff); - - // Step 6.c. - index += 2; - - // Step 6.e. - Ops::store(data++, uint8_t(byte)); - } - } - + size_t alignedLength = length & ~7; + if (index < alignedLength) { auto data32 = data.template cast<uint32_t*>(); // Step 6. - size_t lastValidIndex = length - 8; - while (index <= lastValidIndex) { + while (index < alignedLength) { // Steps 6.a and 6.d. uint32_t word1 = decode4Chars(chars + index); @@ -4459,8 +4433,12 @@ static size_t FromHex(const CharT* chars, size_t length, // Step 6. while (index < length) { - // Step 6.a and 6.d. - uint32_t byte = decode2Chars(chars + index); + // Step 6.a. + auto c0 = chars[index + 0]; + auto c1 = chars[index + 1]; + + // Step 6.d. + uint32_t byte = (decodeChar(c0) << 4) | (decodeChar(c1) << 0); // Step 6.b. if (MOZ_UNLIKELY(int32_t(byte) < 0)) { @@ -5528,31 +5506,6 @@ static void ToBase64(TypedArrayObject* tarray, size_t length, Alphabet alphabet, auto toRead = length; if (toRead >= 12) { - // Align |data| to uint32_t. - if (MOZ_UNLIKELY(data.unwrapValue() & 3)) { - // Performs at most three iterations until |data| is aligned, reading up - // to nine bytes. - while (data.unwrapValue() & 3) { - // Combine three input bytes into a single uint24 value. - auto byte0 = Ops::load(data++); - auto byte1 = Ops::load(data++); - auto byte2 = Ops::load(data++); - auto u24 = (uint32_t(byte0) << 16) | (uint32_t(byte1) << 8) | byte2; - - // Encode the uint24 value as base64. - char chars[] = { - encode(u24 >> 18), - encode(u24 >> 12), - encode(u24 >> 6), - encode(u24 >> 0), - }; - sb.infallibleAppend(chars, sizeof(chars)); - - MOZ_ASSERT(toRead >= 3); - toRead -= 3; - } - } - auto data32 = data.template cast<uint32_t*>(); for (; toRead >= 12; toRead -= 12) { // Read three 32-bit words.