deno_std icon indicating copy to clipboard operation
deno_std copied to clipboard

`bytes/equals` incorrectly handles subarrays

Open tjjfvi opened this issue 2 years ago • 3 comments

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.

tjjfvi avatar Sep 01 '23 11:09 tjjfvi

Maybe equals32Bit is only usable when both a.byteOffset and b.byteOffset are multiple of 4.

cc @Aplet123

kt3k avatar Sep 04 '23 09:09 kt3k

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.

Aplet123 avatar Sep 04 '23 13:09 Aplet123

equals32Bit could also be usable when a.byteOffset % 4 === b.byteOffset % 4 with some small tweaks.

tjjfvi avatar Sep 04 '23 15:09 tjjfvi

Performance fixes applied in #4635.

iuioiua avatar Apr 24 '24 00:04 iuioiua