mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-14 10:26:19 +01:00
fido2-utils: fix BufferSource conversions (#11784)
The original implementation of bufferSourceToUint8Array was incorrect as it did not consider that TypedArray instances represent a view of the underlying ArrayBuffer which does not necessarily cover the entire backing ArrayBuffer. This resulted in the output of this function containing data which would not be logically contained in the input. This was partially fixed by #8787 for the common case of the input already being an Uint8Array, but it was still broken for any other TypedArrays. But #8222 introduced another copy of the original broken code, breaking the Uint8Array case again. Fix this once and hopefully for the last time with a correct implementation of bufferSourceToUint8Array and using that in the appropriate places instead of open-coding it. In addition there are now tests which exercise most edge cases with regards to ArrayBuffer and TypedArrays.
This commit is contained in:
parent
a5294bed3d
commit
6d89c0f157
@ -4,6 +4,36 @@ describe("Fido2 Utils", () => {
|
||||
const asciiHelloWorldArray = [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100];
|
||||
const b64HelloWorldString = "aGVsbG8gd29ybGQ=";
|
||||
|
||||
describe("bufferSourceToUint8Array(..)", () => {
|
||||
it("should convert an ArrayBuffer", () => {
|
||||
const buffer = new Uint8Array(asciiHelloWorldArray).buffer;
|
||||
const out = Fido2Utils.bufferSourceToUint8Array(buffer);
|
||||
expect(out).toEqual(new Uint8Array(asciiHelloWorldArray));
|
||||
});
|
||||
it("should convert an ArrayBuffer slice", () => {
|
||||
const buffer = new Uint8Array(asciiHelloWorldArray).buffer.slice(8);
|
||||
const out = Fido2Utils.bufferSourceToUint8Array(buffer);
|
||||
expect(out).toEqual(new Uint8Array([114, 108, 100])); // 8th byte onwards
|
||||
});
|
||||
it("should pass through an Uint8Array", () => {
|
||||
const typedArray = new Uint8Array(asciiHelloWorldArray);
|
||||
const out = Fido2Utils.bufferSourceToUint8Array(typedArray);
|
||||
expect(out).toEqual(new Uint8Array(asciiHelloWorldArray));
|
||||
});
|
||||
it("should preserve the view of TypedArray", () => {
|
||||
const buffer = new Uint8Array(asciiHelloWorldArray).buffer;
|
||||
const input = new Uint8Array(buffer, 8, 1);
|
||||
const out = Fido2Utils.bufferSourceToUint8Array(input);
|
||||
expect(out).toEqual(new Uint8Array([114]));
|
||||
});
|
||||
it("should convert different TypedArrays", () => {
|
||||
const buffer = new Uint8Array(asciiHelloWorldArray).buffer;
|
||||
const input = new Uint16Array(buffer, 8, 1);
|
||||
const out = Fido2Utils.bufferSourceToUint8Array(input);
|
||||
expect(out).toEqual(new Uint8Array([114, 108]));
|
||||
});
|
||||
});
|
||||
|
||||
describe("fromBufferToB64(...)", () => {
|
||||
it("should convert an ArrayBuffer to a b64 string", () => {
|
||||
const buffer = new Uint8Array(asciiHelloWorldArray).buffer;
|
||||
|
@ -1,13 +1,6 @@
|
||||
export class Fido2Utils {
|
||||
static bufferToString(bufferSource: BufferSource): string {
|
||||
let buffer: Uint8Array;
|
||||
if (bufferSource instanceof ArrayBuffer || bufferSource.buffer === undefined) {
|
||||
buffer = new Uint8Array(bufferSource as ArrayBuffer);
|
||||
} else {
|
||||
buffer = new Uint8Array(bufferSource.buffer);
|
||||
}
|
||||
|
||||
return Fido2Utils.fromBufferToB64(buffer)
|
||||
return Fido2Utils.fromBufferToB64(Fido2Utils.bufferSourceToUint8Array(bufferSource))
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=/g, "");
|
||||
@ -18,12 +11,10 @@ export class Fido2Utils {
|
||||
}
|
||||
|
||||
static bufferSourceToUint8Array(bufferSource: BufferSource): Uint8Array {
|
||||
if (bufferSource instanceof Uint8Array) {
|
||||
return bufferSource;
|
||||
} else if (Fido2Utils.isArrayBuffer(bufferSource)) {
|
||||
if (Fido2Utils.isArrayBuffer(bufferSource)) {
|
||||
return new Uint8Array(bufferSource);
|
||||
} else {
|
||||
return new Uint8Array(bufferSource.buffer);
|
||||
return new Uint8Array(bufferSource.buffer, bufferSource.byteOffset, bufferSource.byteLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user