deno_std
deno_std copied to clipboard
`bytes/equals` incorrectly handles subarrays
import { assert, assertEquals } from "https://deno.land/[email protected]/assert/mod.ts"
import { equals } from "https://deno.land/[email protected]/bytes/equals.ts"
const a = new Uint8Array(1001).subarray(1)
const b = new Uint8Array(1000)
a[0] = 123
b[0] = 123
assertEquals(a, b) // ok
assert(equals(a, b)) // error; false negative
import { assert, assertNotEquals } from "https://deno.land/[email protected]/assert/mod.ts"
import { equals } from "https://deno.land/[email protected]/bytes/equals.ts"
const a = new Uint8Array(1001).subarray(1)
const b = new Uint8Array(1000)
a[999] = 123
assertNotEquals(a, b) // ok
assert(!equals(a, b)) // error; false positive
The equals32Bit implementation does not account for subarrays.
Maybe equals32Bit is only usable when both a.byteOffset and b.byteOffset are multiple of 4.
cc @Aplet123
I think it would take some benchmarking to see if it's better to do the 8 bit approach when byteOffset isn't a multiple of 4 vs constructing a new Uint8Array from the sliced one so there's no longer any byte offset.
equals32Bit could also be usable when a.byteOffset % 4 === b.byteOffset % 4 with some small tweaks.
Performance fixes applied in #4635.