fix(ext/node): fix buffer.includes edge cases (#29591)

This commit is contained in:
Yoshiya Hinosawa 2025-06-04 14:39:27 +09:00 committed by GitHub
parent ff8160b594
commit 0f6d515c91
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 48 deletions

View file

@ -36,18 +36,6 @@ export function indexOfNeedle(
return -1;
}
export function numberToBytes(n: number): Uint8Array {
if (n === 0) return new Uint8Array([0]);
const bytes = [];
bytes.unshift(n & 255);
while (n >= 256) {
n = n >>> 8;
bytes.unshift(n & 255);
}
return new Uint8Array(bytes);
}
// TODO(Soremwar)
// Check if offset or buffer can be transform in order to just use std's lastIndexOf directly
// This implementation differs from std's lastIndexOf in the fact that
@ -101,8 +89,6 @@ function findLastIndex(
return searchableBufferLastIndex - index;
}
// TODO(@bartlomieju):
// Take encoding into account when evaluating index
function indexOfBuffer(
targetBuffer: Uint8Array,
buffer: Uint8Array,
@ -114,6 +100,14 @@ function indexOfBuffer(
throw new Error(`Unknown encoding code ${encoding}`);
}
// If the encoding is UCS2 and haystack or needle has a length less than 2, the search will always fail
// https://github.com/nodejs/node/blob/fbdfe9399cf6c660e67fd7d6ceabfb106e32d787/src/node_buffer.cc#L1067-L1069
if (encoding === Encodings.UCS2) {
if (buffer.length < 2 || targetBuffer.length < 2) {
return -1;
}
}
if (!forwardDirection) {
// If negative the offset is calculated from the end of the buffer
@ -137,23 +131,17 @@ function indexOfBuffer(
return indexOfNeedle(targetBuffer, buffer, byteOffset);
}
// TODO(Soremwar)
// Node's implementation is a very obscure algorithm that I haven't been able to crack just yet
function indexOfNumber(
targetBuffer: Uint8Array,
number: number,
byteOffset: number,
forwardDirection: boolean,
) {
const bytes = numberToBytes(number);
if (bytes.length > 1) {
throw new Error("Multi byte number search is not supported");
}
return indexOfBuffer(
targetBuffer,
numberToBytes(number),
// Uses only the last 2 hex digits of the number
// https://github.com/nodejs/node/issues/7591#issuecomment-231178104
Uint8Array.from([number & 255]),
byteOffset,
Encodings.UTF8,
forwardDirection,