From 0186b898f981e5bd78f1e164cc28c21e22553e23 Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Thu, 30 Nov 2023 21:57:42 +0900 Subject: [PATCH 01/13] perf(fetch): Improve data url base64 --- lib/fetch/dataURL.js | 88 ++++++++++++++++++++++---------------------- lib/fetch/util.js | 31 ++++++++++++---- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index 7b6a606106d..178d1c2558f 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -1,5 +1,4 @@ const assert = require('assert') -const { atob } = require('buffer') const { isomorphicDecode } = require('./util') const encoder = new TextEncoder() @@ -8,7 +7,8 @@ const encoder = new TextEncoder() * @see https://mimesniff.spec.whatwg.org/#http-token-code-point */ const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/ -const HTTP_WHITESPACE_REGEX = /(\u000A|\u000D|\u0009|\u0020)/ // eslint-disable-line +const HTTP_WHITESPACE_REGEX = /[\u000A|\u000D|\u0009|\u0020]/ // eslint-disable-line +const ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g // eslint-disable-line /** * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point */ @@ -26,7 +26,7 @@ function dataURLProcessor (dataURL) { let input = URLSerializer(dataURL, true) // 3. Remove the leading "data:" string from input. - input = input.slice(5) + input = input.substring(5) // 4. Let position point at the start of input. const position = { position: 0 } @@ -59,7 +59,7 @@ function dataURLProcessor (dataURL) { position.position++ // 9. Let encodedBody be the remainder of input. - const encodedBody = input.slice(mimeTypeLength + 1) + const encodedBody = input.substring(mimeTypeLength + 1) // 10. Let body be the percent-decoding of encodedBody. let body = stringPercentDecode(encodedBody) @@ -165,11 +165,11 @@ function collectASequenceOfCodePointsFast (char, input, position) { if (idx === -1) { position.position = input.length - return input.slice(start) + return input.substring(start) } position.position = idx - return input.slice(start, position.position) + return input.substring(start, position.position) } // https://url.spec.whatwg.org/#string-percent-decode @@ -182,20 +182,25 @@ function stringPercentDecode (input) { return percentDecode(bytes) } +function isHexCharByte (byte) { + return (byte >= 0x30 && byte <= 0x39) || (byte >= 0x41 && byte <= 0x46) || (byte >= 0x61 && byte <= 0x66) +} + // https://url.spec.whatwg.org/#percent-decode /** @param {Uint8Array} input */ function percentDecode (input) { // 1. Let output be an empty byte sequence. - /** @type {number[]} */ - const output = [] - + const length = input.length + /** @type {Uint8Array} */ + const output = new Uint8Array(length) + let j = 0 // 2. For each byte byte in input: - for (let i = 0; i < input.length; i++) { + for (let i = 0; i < length; ++i) { const byte = input[i] // 1. If byte is not 0x25 (%), then append byte to output. if (byte !== 0x25) { - output.push(byte) + output[j++] = (byte) // 2. Otherwise, if byte is 0x25 (%) and the next two bytes // after byte in input are not in the ranges @@ -204,9 +209,9 @@ function percentDecode (input) { // to output. } else if ( byte === 0x25 && - !/^[0-9A-Fa-f]{2}$/i.test(String.fromCharCode(input[i + 1], input[i + 2])) + !(isHexCharByte(input[i + 1]) && isHexCharByte(input[i + 2])) ) { - output.push(0x25) + output[j++] = (0x25) // 3. Otherwise: } else { @@ -216,7 +221,7 @@ function percentDecode (input) { const bytePoint = Number.parseInt(nextTwoBytes, 16) // 2. Append a byte whose value is bytePoint to output. - output.push(bytePoint) + output[j++] = (bytePoint) // 3. Skip the next two bytes in input. i += 2 @@ -224,7 +229,7 @@ function percentDecode (input) { } // 3. Return output. - return Uint8Array.from(output) + return length === j ? output : output.subarray(0, j) } // https://mimesniff.spec.whatwg.org/#parse-a-mime-type @@ -404,7 +409,7 @@ function parseMIMEType (input) { /** @param {string} data */ function forgivingBase64 (data) { // 1. Remove all ASCII whitespace from data. - data = data.replace(/[\u0009\u000A\u000C\u000D\u0020]/g, '') // eslint-disable-line + data = data.replace(ASCII_WHITESPACE_REPLACE_REGEX, '') // eslint-disable-line // 2. If data’s code point length divides by 4 leaving // no remainder, then: @@ -429,14 +434,8 @@ function forgivingBase64 (data) { return 'failure' } - const binary = atob(data) - const bytes = new Uint8Array(binary.length) - - for (let byte = 0; byte < binary.length; byte++) { - bytes[byte] = binary.charCodeAt(byte) - } - - return bytes + const buffer = Buffer.from(data, 'base64') + return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) } // https://fetch.spec.whatwg.org/#collect-an-http-quoted-string @@ -515,7 +514,7 @@ function collectAnHTTPQuotedString (input, position, extractValue) { // 7. Return the code points from positionStart to position, // inclusive, within input. - return input.slice(positionStart, position.position) + return input.substring(positionStart, position.position) } /** @@ -564,55 +563,54 @@ function serializeAMimeType (mimeType) { /** * @see https://fetch.spec.whatwg.org/#http-whitespace - * @param {string} char + * @param {number} char */ function isHTTPWhiteSpace (char) { - return char === '\r' || char === '\n' || char === '\t' || char === ' ' + // "\r\n\t " + return char === 0x00d || char === 0x00a || char === 0x009 || char === 0x020 } /** * @see https://fetch.spec.whatwg.org/#http-whitespace * @param {string} str + * @param {boolean} [leading=true] + * @param {boolean} [trailing=true] */ function removeHTTPWhitespace (str, leading = true, trailing = true) { - let lead = 0 - let trail = str.length - 1 - + let i = 0; let j = str.length if (leading) { - for (; lead < str.length && isHTTPWhiteSpace(str[lead]); lead++); + while (j > i && isHTTPWhiteSpace(str.charCodeAt(i))) --i } - if (trailing) { - for (; trail > 0 && isHTTPWhiteSpace(str[trail]); trail--); + while (j > i && isHTTPWhiteSpace(str.charCodeAt(j - 1))) --j } - - return str.slice(lead, trail + 1) + return i === 0 && j === str.length ? str : str.substring(i, j) } /** * @see https://infra.spec.whatwg.org/#ascii-whitespace - * @param {string} char + * @param {number} char */ function isASCIIWhitespace (char) { - return char === '\r' || char === '\n' || char === '\t' || char === '\f' || char === ' ' + // "\r\n\t\f " + return char === 0x00d || char === 0x00a || char === 0x009 || char === 0x00c || char === 0x020 } /** * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace + * @param {string} str + * @param {boolean} [leading=true] + * @param {boolean} [trailing=true] */ function removeASCIIWhitespace (str, leading = true, trailing = true) { - let lead = 0 - let trail = str.length - 1 - + let i = 0; let j = str.length if (leading) { - for (; lead < str.length && isASCIIWhitespace(str[lead]); lead++); + while (j > i && isASCIIWhitespace(str.charCodeAt(i))) --i } - if (trailing) { - for (; trail > 0 && isASCIIWhitespace(str[trail]); trail--); + while (j > i && isASCIIWhitespace(str.charCodeAt(j - 1))) --j } - - return str.slice(lead, trail + 1) + return i === 0 && j === str.length ? str : str.substring(i, j) } module.exports = { diff --git a/lib/fetch/util.js b/lib/fetch/util.js index b12142c7f42..99b9111eb03 100644 --- a/lib/fetch/util.js +++ b/lib/fetch/util.js @@ -904,8 +904,6 @@ function isReadableStreamLike (stream) { ) } -const MAXIMUM_ARGUMENT_LENGTH = 65535 - /** * @see https://infra.spec.whatwg.org/#isomorphic-decode * @param {number[]|Uint8Array} input @@ -914,12 +912,31 @@ function isomorphicDecode (input) { // 1. To isomorphic decode a byte sequence input, return a string whose code point // length is equal to input’s length and whose code points have the same values // as the values of input’s bytes, in the same order. - - if (input.length < MAXIMUM_ARGUMENT_LENGTH) { - return String.fromCharCode(...input) + const length = input.length + if ((2 << 15) - 1 > length) { + return String.fromCharCode.apply(null, input) } - - return input.reduce((previous, current) => previous + String.fromCharCode(current), '') + let result = ''; let i = 0 + if ('buffer' in input) { + let addition = (2 << 15) - 1 + while (i < length) { + if (i + addition > length) { + addition = length - i + } + result += String.fromCharCode.apply(null, input.subarray(i, i += addition)) + } + return result + } + // FIXME: Is there really a case here? + while (i + 32 < length) { + result += String.fromCharCode(input[i], input[i + 1], input[i + 2], input[i + 3], input[i + 4], input[i + 5], input[i + 6], input[i + 7], input[i + 8], input[i + 9], input[i + 10], input[i + 11], input[i + 12], input[i + 13], input[i + 14], input[i + 15], input[i + 16], input[i + 17], input[i + 18], input[i + 19], input[i + 20], input[i + 21], input[i + 22], input[i + 23], input[i + 24], input[i + 25], input[i + 26], input[i + 27], input[i + 28], input[i + 29], input[i + 30], input[i + 31]) + i += 32 + } + // Decode the remaining characters. + while (i < length) { + result += String.fromCharCode(input[i++]) + } + return result } /** From ed8f08e2629f45f05ed0683179a5bdfcc4fe607a Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Thu, 30 Nov 2023 22:02:20 +0900 Subject: [PATCH 02/13] format --- lib/fetch/dataURL.js | 6 +++--- lib/fetch/util.js | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index 178d1c2558f..fc22d41572d 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -200,7 +200,7 @@ function percentDecode (input) { // 1. If byte is not 0x25 (%), then append byte to output. if (byte !== 0x25) { - output[j++] = (byte) + output[j++] = byte // 2. Otherwise, if byte is 0x25 (%) and the next two bytes // after byte in input are not in the ranges @@ -211,7 +211,7 @@ function percentDecode (input) { byte === 0x25 && !(isHexCharByte(input[i + 1]) && isHexCharByte(input[i + 2])) ) { - output[j++] = (0x25) + output[j++] = 0x25 // 3. Otherwise: } else { @@ -221,7 +221,7 @@ function percentDecode (input) { const bytePoint = Number.parseInt(nextTwoBytes, 16) // 2. Append a byte whose value is bytePoint to output. - output[j++] = (bytePoint) + output[j++] = bytePoint // 3. Skip the next two bytes in input. i += 2 diff --git a/lib/fetch/util.js b/lib/fetch/util.js index 99b9111eb03..273b3e53e8e 100644 --- a/lib/fetch/util.js +++ b/lib/fetch/util.js @@ -929,7 +929,12 @@ function isomorphicDecode (input) { } // FIXME: Is there really a case here? while (i + 32 < length) { - result += String.fromCharCode(input[i], input[i + 1], input[i + 2], input[i + 3], input[i + 4], input[i + 5], input[i + 6], input[i + 7], input[i + 8], input[i + 9], input[i + 10], input[i + 11], input[i + 12], input[i + 13], input[i + 14], input[i + 15], input[i + 16], input[i + 17], input[i + 18], input[i + 19], input[i + 20], input[i + 21], input[i + 22], input[i + 23], input[i + 24], input[i + 25], input[i + 26], input[i + 27], input[i + 28], input[i + 29], input[i + 30], input[i + 31]) + result += String.fromCharCode( + input[i], input[i + 1], input[i + 2], input[i + 3], input[i + 4], input[i + 5], input[i + 6], input[i + 7], + input[i + 8], input[i + 9], input[i + 10], input[i + 11], input[i + 12], input[i + 13], input[i + 14], input[i + 15], + input[i + 16], input[i + 17], input[i + 18], input[i + 19], input[i + 20], input[i + 21], input[i + 22], input[i + 23], + input[i + 24], input[i + 25], input[i + 26], input[i + 27], input[i + 28], input[i + 29], input[i + 30], input[i + 31] + ) i += 32 } // Decode the remaining characters. From 85959c93ff0ea96549d434ee4e3ce3d6167a3b43 Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Thu, 30 Nov 2023 22:31:17 +0900 Subject: [PATCH 03/13] fix: comment position --- lib/fetch/dataURL.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index fc22d41572d..559e7e953c4 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -189,8 +189,8 @@ function isHexCharByte (byte) { // https://url.spec.whatwg.org/#percent-decode /** @param {Uint8Array} input */ function percentDecode (input) { - // 1. Let output be an empty byte sequence. const length = input.length + // 1. Let output be an empty byte sequence. /** @type {Uint8Array} */ const output = new Uint8Array(length) let j = 0 From e6cc7156b5726ad915ace818a4338cf56c8c9334 Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Thu, 30 Nov 2023 22:33:17 +0900 Subject: [PATCH 04/13] add comment --- lib/fetch/dataURL.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index 559e7e953c4..2448e9c1b9e 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -183,6 +183,7 @@ function stringPercentDecode (input) { } function isHexCharByte (byte) { + // 0-9 A-F a-f return (byte >= 0x30 && byte <= 0x39) || (byte >= 0x41 && byte <= 0x46) || (byte >= 0x61 && byte <= 0x66) } From de7eeeec15031e2d0ea854b50bbd9c87d0e488f8 Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Thu, 30 Nov 2023 22:46:55 +0900 Subject: [PATCH 05/13] add comment --- lib/fetch/util.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/fetch/util.js b/lib/fetch/util.js index 273b3e53e8e..0620dc89a1d 100644 --- a/lib/fetch/util.js +++ b/lib/fetch/util.js @@ -917,6 +917,7 @@ function isomorphicDecode (input) { return String.fromCharCode.apply(null, input) } let result = ''; let i = 0 + // isTypedArray if ('buffer' in input) { let addition = (2 << 15) - 1 while (i < length) { @@ -927,7 +928,7 @@ function isomorphicDecode (input) { } return result } - // FIXME: Is there really a case here? + // FIXME: Is it really possible that an array of numbers is passed on? while (i + 32 < length) { result += String.fromCharCode( input[i], input[i + 1], input[i + 2], input[i + 3], input[i + 4], input[i + 5], input[i + 6], input[i + 7], From 99a9f09ba044bfb16c8181e0e043a9f54eda420d Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Fri, 1 Dec 2023 06:43:13 +0900 Subject: [PATCH 06/13] suggestion change --- lib/fetch/dataURL.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index 2448e9c1b9e..aff8403f0cd 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -26,7 +26,7 @@ function dataURLProcessor (dataURL) { let input = URLSerializer(dataURL, true) // 3. Remove the leading "data:" string from input. - input = input.substring(5) + input = input.slice(5) // 4. Let position point at the start of input. const position = { position: 0 } @@ -59,7 +59,7 @@ function dataURLProcessor (dataURL) { position.position++ // 9. Let encodedBody be the remainder of input. - const encodedBody = input.substring(mimeTypeLength + 1) + const encodedBody = input.slice(mimeTypeLength + 1) // 10. Let body be the percent-decoding of encodedBody. let body = stringPercentDecode(encodedBody) @@ -165,11 +165,11 @@ function collectASequenceOfCodePointsFast (char, input, position) { if (idx === -1) { position.position = input.length - return input.substring(start) + return input.slice(start) } position.position = idx - return input.substring(start, position.position) + return input.slice(start, position.position) } // https://url.spec.whatwg.org/#string-percent-decode @@ -515,7 +515,7 @@ function collectAnHTTPQuotedString (input, position, extractValue) { // 7. Return the code points from positionStart to position, // inclusive, within input. - return input.substring(positionStart, position.position) + return input.slice(positionStart, position.position) } /** From cd93cdb5562f542db5eee4b758921632c2de0e25 Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Fri, 1 Dec 2023 09:07:01 +0900 Subject: [PATCH 07/13] perf: avoid replace --- lib/fetch/dataURL.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index aff8403f0cd..04b5c39af23 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -412,17 +412,20 @@ function forgivingBase64 (data) { // 1. Remove all ASCII whitespace from data. data = data.replace(ASCII_WHITESPACE_REPLACE_REGEX, '') // eslint-disable-line + let dataLength = data.length // 2. If data’s code point length divides by 4 leaving // no remainder, then: - if (data.length % 4 === 0) { + if (dataLength % 4 === 0) { // 1. If data ends with one or two U+003D (=) code points, // then remove them from data. - data = data.replace(/=?=$/, '') + if (data.charCodeAt(dataLength - 1) === 0x003D && data.charCodeAt(--dataLength) === 0x003D) { + --dataLength + } } // 3. If data’s code point length divides by 4 leaving // a remainder of 1, then return failure. - if (data.length % 4 === 1) { + if (dataLength % 4 === 1) { return 'failure' } @@ -431,7 +434,7 @@ function forgivingBase64 (data) { // U+002F (/) // ASCII alphanumeric // then return failure. - if (/[^+/0-9A-Za-z]/.test(data)) { + if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : (data = data.substring(0, dataLength)))) { return 'failure' } From 058dc02d3509b19957379ad227c020df99bf7e3d Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Fri, 1 Dec 2023 09:08:36 +0900 Subject: [PATCH 08/13] fixup --- lib/fetch/dataURL.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index 04b5c39af23..e5d4ca1fa4a 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -418,8 +418,11 @@ function forgivingBase64 (data) { if (dataLength % 4 === 0) { // 1. If data ends with one or two U+003D (=) code points, // then remove them from data. - if (data.charCodeAt(dataLength - 1) === 0x003D && data.charCodeAt(--dataLength) === 0x003D) { + if (data.charCodeAt(dataLength - 1) === 0x003D) { --dataLength + if (data.charCodeAt(dataLength - 1) === 0x003D) { + --dataLength + } } } From 6e4588cf5ecebe8e8e764a99a19831ec29c38bf8 Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Fri, 1 Dec 2023 09:13:41 +0900 Subject: [PATCH 09/13] refactor --- lib/fetch/dataURL.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index e5d4ca1fa4a..9e8c15e3273 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -437,7 +437,7 @@ function forgivingBase64 (data) { // U+002F (/) // ASCII alphanumeric // then return failure. - if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : (data = data.substring(0, dataLength)))) { + if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : data.substring(0, dataLength))) { return 'failure' } From 05a4721408493eb7d380b63a08a0010fb560c699 Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Fri, 1 Dec 2023 09:19:15 +0900 Subject: [PATCH 10/13] fixup --- lib/fetch/dataURL.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index 9e8c15e3273..e5d4ca1fa4a 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -437,7 +437,7 @@ function forgivingBase64 (data) { // U+002F (/) // ASCII alphanumeric // then return failure. - if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : data.substring(0, dataLength))) { + if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : (data = data.substring(0, dataLength)))) { return 'failure' } From a7ff05a4e128589c4c114c62ac2362dc9fad1338 Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Fri, 1 Dec 2023 10:20:17 +0900 Subject: [PATCH 11/13] Revert "fixup" This reverts commit 058dc02d3509b19957379ad227c020df99bf7e3d. --- lib/fetch/dataURL.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index e5d4ca1fa4a..04b5c39af23 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -418,11 +418,8 @@ function forgivingBase64 (data) { if (dataLength % 4 === 0) { // 1. If data ends with one or two U+003D (=) code points, // then remove them from data. - if (data.charCodeAt(dataLength - 1) === 0x003D) { + if (data.charCodeAt(dataLength - 1) === 0x003D && data.charCodeAt(--dataLength) === 0x003D) { --dataLength - if (data.charCodeAt(dataLength - 1) === 0x003D) { - --dataLength - } } } From 269c7c4f29561c3f2704bf3b2e7ea8a90b1c08d5 Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Fri, 1 Dec 2023 10:22:30 +0900 Subject: [PATCH 12/13] fixup --- lib/fetch/dataURL.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/fetch/dataURL.js b/lib/fetch/dataURL.js index 04b5c39af23..9e8c15e3273 100644 --- a/lib/fetch/dataURL.js +++ b/lib/fetch/dataURL.js @@ -418,8 +418,11 @@ function forgivingBase64 (data) { if (dataLength % 4 === 0) { // 1. If data ends with one or two U+003D (=) code points, // then remove them from data. - if (data.charCodeAt(dataLength - 1) === 0x003D && data.charCodeAt(--dataLength) === 0x003D) { + if (data.charCodeAt(dataLength - 1) === 0x003D) { --dataLength + if (data.charCodeAt(dataLength - 1) === 0x003D) { + --dataLength + } } } @@ -434,7 +437,7 @@ function forgivingBase64 (data) { // U+002F (/) // ASCII alphanumeric // then return failure. - if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : (data = data.substring(0, dataLength)))) { + if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : data.substring(0, dataLength))) { return 'failure' } From 7a95eb8bb71caabc6362d5d84f9aeeee82d0529e Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Sun, 3 Dec 2023 23:46:02 +0900 Subject: [PATCH 13/13] remove --- lib/fetch/util.js | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/lib/fetch/util.js b/lib/fetch/util.js index 934ef8a6dab..b729d70d1e8 100644 --- a/lib/fetch/util.js +++ b/lib/fetch/util.js @@ -899,7 +899,7 @@ function isReadableStreamLike (stream) { /** * @see https://infra.spec.whatwg.org/#isomorphic-decode - * @param {number[]|Uint8Array} input + * @param {Uint8Array} input */ function isomorphicDecode (input) { // 1. To isomorphic decode a byte sequence input, return a string whose code point @@ -910,30 +910,12 @@ function isomorphicDecode (input) { return String.fromCharCode.apply(null, input) } let result = ''; let i = 0 - // isTypedArray - if ('buffer' in input) { - let addition = (2 << 15) - 1 - while (i < length) { - if (i + addition > length) { - addition = length - i - } - result += String.fromCharCode.apply(null, input.subarray(i, i += addition)) - } - return result - } - // FIXME: Is it really possible that an array of numbers is passed on? - while (i + 32 < length) { - result += String.fromCharCode( - input[i], input[i + 1], input[i + 2], input[i + 3], input[i + 4], input[i + 5], input[i + 6], input[i + 7], - input[i + 8], input[i + 9], input[i + 10], input[i + 11], input[i + 12], input[i + 13], input[i + 14], input[i + 15], - input[i + 16], input[i + 17], input[i + 18], input[i + 19], input[i + 20], input[i + 21], input[i + 22], input[i + 23], - input[i + 24], input[i + 25], input[i + 26], input[i + 27], input[i + 28], input[i + 29], input[i + 30], input[i + 31] - ) - i += 32 - } - // Decode the remaining characters. + let addition = (2 << 15) - 1 while (i < length) { - result += String.fromCharCode(input[i++]) + if (i + addition > length) { + addition = length - i + } + result += String.fromCharCode.apply(null, input.subarray(i, i += addition)) } return result }