Skip to content

Commit

Permalink
fix: [#1565] Validate that object is of type Blob in FileReader.readA…
Browse files Browse the repository at this point in the history
…sArrayBuffer, FileReader.readAsBinaryString, FileReader.readAsDataURL and FileReader.readAsText (#1575)

* fix: [#1565] Strictly check the type of `blob` parameters

* chore: [#1565] Uses TypeError from Window, as BrowserExceptionObserver can then detect the origin of the error

* chore: [#1565] Fixes linting error

---------

Co-authored-by: David Ortner <david@ortner.se>
  • Loading branch information
btea and capricorn86 authored Nov 6, 2024
1 parent 343bc49 commit 6ff0d8f
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 0 deletions.
20 changes: 20 additions & 0 deletions packages/happy-dom/src/file/FileReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ export default class FileReader extends EventTarget {
* @param blob Blob.
*/
public readAsArrayBuffer(blob: Blob): void {
if (!(blob instanceof Blob)) {
throw new this[PropertySymbol.window].TypeError(
`Failed to execute 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'.`
);
}
this.#readFile(blob, FileReaderFormatEnum.buffer);
}

Expand All @@ -58,6 +63,11 @@ export default class FileReader extends EventTarget {
* @param blob Blob.
*/
public readAsBinaryString(blob: Blob): void {
if (!(blob instanceof Blob)) {
throw new this[PropertySymbol.window].TypeError(
`Failed to execute 'readAsBinaryString' on 'FileReader': parameter 1 is not of type 'Blob'.`
);
}
this.#readFile(blob, FileReaderFormatEnum.binaryString);
}

Expand All @@ -67,6 +77,11 @@ export default class FileReader extends EventTarget {
* @param blob Blob.
*/
public readAsDataURL(blob: Blob): void {
if (!(blob instanceof Blob)) {
throw new this[PropertySymbol.window].TypeError(
`Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.`
);
}
this.#readFile(blob, FileReaderFormatEnum.dataURL);
}

Expand All @@ -77,6 +92,11 @@ export default class FileReader extends EventTarget {
* @param [encoding] Encoding.
*/
public readAsText(blob: Blob, encoding: string | null = null): void {
if (!(blob instanceof Blob)) {
throw new this[PropertySymbol.window].TypeError(
`Failed to execute 'readAsText' on 'FileReader': parameter 1 is not of type 'Blob'.`
);
}
this.#readFile(blob, FileReaderFormatEnum.text, encoding || 'UTF-8');
}

Expand Down
77 changes: 77 additions & 0 deletions packages/happy-dom/test/file/FileReader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,82 @@ describe('FileReader', () => {
await window.happyDOM?.waitUntilComplete();
expect(result).toBe('data:text/plain;charset=utf-8;base64,VEVTVA==');
});

it('Reads Blob as data URL passing invalid parameter.', () => {
expect(() => {
fileReader.readAsDataURL(<any>'invalid');
}).toThrow(
`Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.`
);
});
});

describe('readAsText()', () => {
it('Reads Blob as text.', async () => {
const blob = new Blob(['TEST'], {
type: 'text/plain;charset=utf-8'
});
let result: string | null = null;
fileReader.addEventListener('load', () => {
result = <string>fileReader.result;
});
fileReader.readAsText(blob);
await window.happyDOM?.waitUntilComplete();
expect(result).toBe('TEST');
});

it('Reads Blob as text passing invalid parameter.', () => {
expect(() => {
fileReader.readAsText(<any>'invalid');
}).toThrow(
`Failed to execute 'readAsText' on 'FileReader': parameter 1 is not of type 'Blob'.`
);
});
});

describe('readAsArrayBuffer()', () => {
it('Reads Blob as array buffer.', async () => {
const blob = new Blob(['TEST'], {
type: 'text/plain;charset=utf-8'
});
let result: ArrayBuffer | null = null;
fileReader.addEventListener('load', () => {
result = <ArrayBuffer>fileReader.result;
});
fileReader.readAsArrayBuffer(blob);
await window.happyDOM?.waitUntilComplete();
expect(result).toBeInstanceOf(ArrayBuffer);
});

it('Reads Blob as array buffer passing invalid parameter.', () => {
expect(() => {
fileReader.readAsArrayBuffer(<any>'invalid');
}).toThrow(
`Failed to execute 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'.`
);
});
});

describe('readAsBinaryString()', () => {
it('Reads Blob as binary string.', async () => {
const blob = new Blob(['TEST'], {
type: 'text/plain;charset=utf-8'
});
let result: string | null = null;
fileReader.addEventListener('load', () => {
result = <string>fileReader.result;
});
fileReader.readAsBinaryString(blob);
await window.happyDOM?.waitUntilComplete();
expect(result).toBe('TEST');
});

it('Reads Blob as binary string passing invalid parameter.', () => {
expect(() => {
fileReader.readAsBinaryString(<any>'invalid');
}).toThrow(
`Failed to execute 'readAsBinaryString' on 'FileReader': parameter 1 is not of type 'Blob'.`
);
});
});
});

0 comments on commit 6ff0d8f

Please sign in to comment.