diff --git a/packages/react-native-quick-crypto/src/utils/conversion.ts b/packages/react-native-quick-crypto/src/utils/conversion.ts index 3a9f7566..c8a7fde2 100644 --- a/packages/react-native-quick-crypto/src/utils/conversion.ts +++ b/packages/react-native-quick-crypto/src/utils/conversion.ts @@ -93,7 +93,7 @@ export function rejectSharedArrayBuffer(buf: unknown): void { * Only use this when the caller separately tracks `byteOffset`/`byteLength` * and the native receiver needs to write back into the original memory * (e.g. `randomFill`). For data that will be read by native crypto, use - * `binaryLikeToArrayBuffer`/`toArrayBuffer` instead — those slice to the + * `binaryLikeToArrayBuffer`/`toArrayBuffer` instead — those return only the * view's region and won't leak unrelated bytes from the backing buffer. */ export const abvToArrayBuffer = (buf: ABV) => { @@ -108,8 +108,10 @@ export const abvToArrayBuffer = (buf: ABV) => { }; /** - * Converts supplied argument to an ArrayBuffer. Note this copies data if the - * supplied buffer has the .slice() method, so can be a bit slow. + * Converts supplied argument to an ArrayBuffer. Note this copies data + * only when the supplied view represents a subrange of the underlying + * ArrayBuffer; otherwise the backing buffer is returned directly + * (aliased — do not mutate after passing). * @param buf * @returns ArrayBuffer */ @@ -117,13 +119,13 @@ export function toArrayBuffer( buf: CraftzdogBuffer | SafeBuffer | ArrayBufferView, ): ArrayBuffer { if (CraftzdogBuffer.isBuffer(buf) || ArrayBuffer.isView(buf)) { - if (buf?.buffer?.slice) { + if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) { + return buf.buffer as ArrayBuffer; + } else { return buf.buffer.slice( buf.byteOffset, buf.byteOffset + buf.byteLength, ) as ArrayBuffer; - } else { - return buf.buffer as ArrayBuffer; } } const ab = new ArrayBuffer(buf.length);