Replace buffer.slice() with buffer.subarray()

This commit is contained in:
Fedor Indutny
2025-06-09 14:37:30 -07:00
committed by GitHub
parent 4a6e2d297b
commit b0634f9a9d
19 changed files with 54 additions and 45 deletions

View File

@@ -432,7 +432,7 @@ export function trimForDisplay(padded: Uint8Array): Uint8Array {
break;
}
}
return padded.slice(0, paddingEnd);
return padded.subarray(0, paddingEnd);
}
function verifyDigest(data: Uint8Array, theirDigest: Uint8Array): void {
@@ -459,13 +459,16 @@ export function decryptAttachmentV1(
throw new Error('Got invalid length attachment');
}
const aesKey = keys.slice(0, 32);
const macKey = keys.slice(32, 64);
const aesKey = keys.subarray(0, 32);
const macKey = keys.subarray(32, 64);
const iv = encryptedBin.slice(0, 16);
const ciphertext = encryptedBin.slice(16, encryptedBin.byteLength - 32);
const ivAndCiphertext = encryptedBin.slice(0, encryptedBin.byteLength - 32);
const mac = encryptedBin.slice(
const iv = encryptedBin.subarray(0, 16);
const ciphertext = encryptedBin.subarray(16, encryptedBin.byteLength - 32);
const ivAndCiphertext = encryptedBin.subarray(
0,
encryptedBin.byteLength - 32
);
const mac = encryptedBin.subarray(
encryptedBin.byteLength - 32,
encryptedBin.byteLength
);
@@ -504,8 +507,8 @@ export function encryptAttachment({
}
const iv = dangerousTestOnlyIv || getRandomBytes(16);
const aesKey = keys.slice(0, 32);
const macKey = keys.slice(32, 64);
const aesKey = keys.subarray(0, 32);
const macKey = keys.subarray(32, 64);
const ciphertext = encryptAes256CbcPkcsPadding(aesKey, plaintext, iv);
@@ -564,8 +567,8 @@ export function decryptProfile(data: Uint8Array, key: Uint8Array): Uint8Array {
if (data.byteLength < 12 + 16 + 1) {
throw new Error(`Got too short input: ${data.byteLength}`);
}
const iv = data.slice(0, PROFILE_IV_LENGTH);
const ciphertext = data.slice(PROFILE_IV_LENGTH, data.byteLength);
const iv = data.subarray(0, PROFILE_IV_LENGTH);
const ciphertext = data.subarray(PROFILE_IV_LENGTH, data.byteLength);
if (key.byteLength !== PROFILE_KEY_LENGTH) {
throw new Error('Got invalid length profile key');
}
@@ -624,8 +627,8 @@ export function decryptProfileName(
const foundFamilyName = familyEnd > givenEnd + 1;
return {
given: padded.slice(0, givenEnd),
family: foundFamilyName ? padded.slice(givenEnd + 1, familyEnd) : null,
given: padded.subarray(0, givenEnd),
family: foundFamilyName ? padded.subarray(givenEnd + 1, familyEnd) : null,
};
}

View File

@@ -143,7 +143,7 @@ function validatePubKeyFormat(pubKey: Uint8Array): Uint8Array {
throw new Error('Invalid public key');
}
if (pubKey.byteLength === 33) {
return pubKey.slice(1);
return pubKey.subarray(1);
}
return pubKey;

View File

@@ -268,5 +268,5 @@ export function getBucketValue(aci: AciString, flagName: string): number {
hashInput
);
return Number(Bytes.readBigUint64BE(hashResult.slice(0, 8)) % 1_000_000n);
return Number(Bytes.readBigUint64BE(hashResult.subarray(0, 8)) % 1_000_000n);
}

View File

@@ -1923,7 +1923,7 @@ export class SignalProtocolStore extends EventEmitter {
}
const hash = sha256(pubKey);
const fingerprint = hash.slice(0, 4);
const fingerprint = hash.subarray(0, 4);
return Bytes.toBase64(fingerprint);
}

View File

@@ -126,7 +126,7 @@ async function fetchSegment(
let slice: ArrayBufferView;
// Trim duplicate bytes from start of last segment
if (segmentRange.sliceStart > 0) {
slice = data.slice(segmentRange.sliceStart);
slice = data.subarray(segmentRange.sliceStart);
} else {
slice = data;
}

View File

@@ -95,8 +95,8 @@ export class Crypto {
throw new Error('Invalid GCM ciphertext');
}
const tag = input.slice(input.length - AUTH_TAG_SIZE);
input = input.slice(0, input.length - AUTH_TAG_SIZE);
const tag = input.subarray(input.length - AUTH_TAG_SIZE);
input = input.subarray(0, input.length - AUTH_TAG_SIZE);
gcm.setAuthTag(tag);

View File

@@ -307,7 +307,10 @@ const getHtmlDocument = async (
chunk = Buffer.from(chunk, httpCharset || 'utf8');
}
const truncatedChunk = chunk.slice(0, buffer.length - bytesLoadedSoFar);
const truncatedChunk = chunk.subarray(
0,
buffer.length - bytesLoadedSoFar
);
buffer.set(truncatedChunk, bytesLoadedSoFar);
bytesLoadedSoFar += truncatedChunk.byteLength;
@@ -322,7 +325,10 @@ const getHtmlDocument = async (
);
}
const result = parseHtmlBytes(buffer.slice(0, bytesLoadedSoFar), httpCharset);
const result = parseHtmlBytes(
buffer.subarray(0, bytesLoadedSoFar),
httpCharset
);
return result;
};

View File

@@ -32,7 +32,7 @@ export class FileStream extends InputStream {
this.#position
);
this.#position += bytesRead;
return this.#buffer.slice(0, bytesRead);
return this.#buffer.subarray(0, bytesRead);
}
async skip(amount: number): Promise<void> {

View File

@@ -2822,7 +2822,7 @@ export class CallingClass {
);
return;
}
const senderIdentityKey = senderIdentityRecord.publicKey.slice(1); // Ignore the type header, it is not used.
const senderIdentityKey = senderIdentityRecord.publicKey.subarray(1); // Ignore the type header, it is not used.
const ourAci = storage.user.getCheckedAci();
@@ -2833,7 +2833,7 @@ export class CallingClass {
);
return;
}
const receiverIdentityKey = receiverIdentityRecord.publicKey.slice(1); // Ignore the type header, it is not used.
const receiverIdentityKey = receiverIdentityRecord.publicKey.subarray(1); // Ignore the type header, it is not used.
const conversation = window.ConversationController.get(remoteUserId);
if (!conversation) {

View File

@@ -370,8 +370,8 @@ export async function resolveUsernameByLinkBase64(
base64: string
): Promise<string | undefined> {
const content = Bytes.fromBase64(base64);
const entropy = content.slice(0, USERNAME_LINK_ENTROPY_SIZE);
const serverId = content.slice(USERNAME_LINK_ENTROPY_SIZE);
const entropy = content.subarray(0, USERNAME_LINK_ENTROPY_SIZE);
const serverId = content.subarray(USERNAME_LINK_ENTROPY_SIZE);
return resolveUsernameByLink({ entropy, serverId });
}

View File

@@ -35,11 +35,11 @@ describe('appendMacStream', () => {
const expectedMac = hmac.digest();
assert.strictEqual(
buf.slice(0, -MAC_SIZE).toString('hex'),
buf.subarray(0, -MAC_SIZE).toString('hex'),
plaintext.toString('hex')
);
assert.strictEqual(
buf.slice(-MAC_SIZE).toString('hex'),
buf.subarray(-MAC_SIZE).toString('hex'),
expectedMac.toString('hex')
);
});

View File

@@ -102,7 +102,7 @@ describe('appendPaddingStream', () => {
}
}
assert.strictEqual(buf.slice(0, -padding).toString(), inputs.join(''));
assert.strictEqual(buf.subarray(0, -padding).toString(), inputs.join(''));
assert.strictEqual(buf.length, expectedSize);
}

View File

@@ -385,7 +385,7 @@ describe('Crypto', () => {
const key = getRandomBytes(32);
const plaintext = Bytes.fromString('Hello world');
const ourMac = hmacSha256(key, plaintext);
const theirMac = ourMac.slice(0, -1);
const theirMac = ourMac.subarray(0, -1);
let error;
try {
verifyHmacSha256(plaintext, key, theirMac, ourMac.byteLength);
@@ -458,7 +458,7 @@ describe('Crypto', () => {
it('resolves with undefined if the first `length` bytes of the MACs match', () => {
const key = getRandomBytes(32);
const plaintext = Bytes.fromString('Hello world');
const theirMac = hmacSha256(key, plaintext).slice(0, -5);
const theirMac = hmacSha256(key, plaintext).subarray(0, -5);
const result = verifyHmacSha256(
plaintext,
key,

View File

@@ -33,7 +33,7 @@ describe('DelimitedStream', () => {
Readable.from(
(function* () {
for (let offset = 0; offset < data.length; offset += stride) {
yield data.slice(offset, offset + stride);
yield data.subarray(offset, offset + stride);
}
})()
),
@@ -95,7 +95,7 @@ describe('DelimitedStream', () => {
const out = new Array<string>();
await assert.isRejected(
pipeline(
Readable.from(w.finish().slice(0, 1)),
Readable.from(w.finish().subarray(0, 1)),
new DelimitedStream(),
collect(out)
),
@@ -110,7 +110,7 @@ describe('DelimitedStream', () => {
const out = new Array<string>();
await assert.isRejected(
pipeline(
Readable.from(w.finish().slice(0, 10)),
Readable.from(w.finish().subarray(0, 10)),
new DelimitedStream(),
collect(out)
),

View File

@@ -143,7 +143,7 @@ export class ParseContactsTransform extends Transform {
const spaceLeftAfterRead = reader.len - (reader.pos + attachmentSize);
if (spaceLeftAfterRead >= 0) {
// We've read enough data to read the entire attachment
const avatarData = reader.buf.slice(
const avatarData = reader.buf.subarray(
reader.pos,
reader.pos + attachmentSize
);

View File

@@ -1659,7 +1659,7 @@ export default class MessageReceiver
#unpad(paddedPlaintext: Uint8Array): Uint8Array {
for (let i = paddedPlaintext.length - 1; i >= 0; i -= 1) {
if (paddedPlaintext[i] === 0x80) {
return new Uint8Array(paddedPlaintext.slice(0, i));
return new Uint8Array(paddedPlaintext.subarray(0, i));
}
if (paddedPlaintext[i] !== 0x00) {
throw new Error('Invalid padding');

View File

@@ -47,10 +47,10 @@ class ProvisioningCipherInner {
throw new Error('Bad version number on ProvisioningMessage');
}
const iv = message.slice(1, 16 + 1);
const mac = message.slice(message.byteLength - 32, message.byteLength);
const ivAndCiphertext = message.slice(0, message.byteLength - 32);
const ciphertext = message.slice(16 + 1, message.byteLength - 32);
const iv = message.subarray(1, 16 + 1);
const mac = message.subarray(message.byteLength - 32, message.byteLength);
const ivAndCiphertext = message.subarray(0, message.byteLength - 32);
const ciphertext = message.subarray(16 + 1, message.byteLength - 32);
if (!this.keyPair) {
throw new Error('ProvisioningCipher.decrypt: No keypair!');

View File

@@ -211,7 +211,7 @@ function decodeSingleResponse(
i < response.e164PniAciTriples.length;
i += TRIPLE_BYTE_SIZE
) {
const tripleBytes = response.e164PniAciTriples.slice(
const tripleBytes = response.e164PniAciTriples.subarray(
i,
i + TRIPLE_BYTE_SIZE
);
@@ -221,13 +221,13 @@ function decodeSingleResponse(
);
let offset = 0;
const e164Bytes = tripleBytes.slice(offset, offset + E164_BYTE_SIZE);
const e164Bytes = tripleBytes.subarray(offset, offset + E164_BYTE_SIZE);
offset += E164_BYTE_SIZE;
const pniBytes = tripleBytes.slice(offset, offset + UUID_BYTE_SIZE);
const pniBytes = tripleBytes.subarray(offset, offset + UUID_BYTE_SIZE);
offset += UUID_BYTE_SIZE;
const aciBytes = tripleBytes.slice(offset, offset + UUID_BYTE_SIZE);
const aciBytes = tripleBytes.subarray(offset, offset + UUID_BYTE_SIZE);
offset += UUID_BYTE_SIZE;
const e164Long = Long.fromBytesBE(Array.from(e164Bytes));

View File

@@ -325,7 +325,7 @@ function translateMessageKey(key: Uint8Array) {
return {
cipherKey,
macKey,
iv: ivContainer.slice(0, 16),
iv: ivContainer.subarray(0, 16),
};
}