Skip to content

Commit 2ad7fc2

Browse files
committed
fix: use getAsFileSystemHandle only in secure ctx
1 parent 1a997bd commit 2ad7fc2

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const jestConfig = {
1010
moduleNameMapper: {
1111
"^(\\.{1,2}/.*)\\.js$": "$1",
1212
},
13+
setupFilesAfterEnv: ["<rootDir>/test-setup.js"],
1314
};
1415

1516
export default jestConfig;

src/file-selector.spec.ts

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,41 @@ it("should use getAsFileSystemHandle when available", async () => {
344344
expect(file.path).toBe(`./${name}`);
345345
});
346346

347+
it("should not use getAsFileSystemHandle when not in a secure context", async () => {
348+
const f1Name = "test.nosec.json";
349+
const f1 = createFile(
350+
f1Name,
351+
{ ping: false },
352+
{
353+
type: "application/json",
354+
},
355+
);
356+
const [, h] = createFileSystemFileHandle(
357+
"test.sec.json",
358+
{ ping: true },
359+
{
360+
type: "application/json",
361+
},
362+
);
363+
const evt = dragEvtFromItems([dataTransferItemWithFsHandle(f1, h)]);
364+
365+
globalThis.isSecureContext = false;
366+
367+
const files = await fromEvent(evt);
368+
expect(files).toHaveLength(1);
369+
expect(files.every((file) => file instanceof File)).toBe(true);
370+
371+
const [file] = files as FileWithPath[];
372+
373+
expect(file.name).toBe(f1.name);
374+
expect(file.type).toBe(f1.type);
375+
expect(file.size).toBe(f1.size);
376+
expect(file.lastModified).toBe(f1.lastModified);
377+
expect(file.path).toBe(`./${f1Name}`);
378+
379+
globalThis.isSecureContext = true;
380+
});
381+
347382
function dragEvtFromItems(
348383
items: DataTransferItem | DataTransferItem[],
349384
type: string = "drop",
@@ -519,8 +554,7 @@ function createFileSystemFileHandle<T>(
519554
data: T,
520555
options?: FilePropertyBag,
521556
): [File, FileSystemFileHandle] {
522-
const json = JSON.stringify(data);
523-
const file = new File([json], name, options);
557+
const file = createFile(name, data, options);
524558
return [
525559
file,
526560
{

src/file-selector.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,15 @@ function fromDataTransferItem(
109109
item: DataTransferItem,
110110
entry?: FileSystemEntry | null,
111111
) {
112-
if (typeof (item as any).getAsFileSystemHandle === "function") {
112+
// Check if we're in a secure context; due to a bug in Chrome (as far as we know) the browser crashes when calling this API (yet to be confirmed as a consistent behavior).
113+
//
114+
// See:
115+
// - https://issues.chromium.org/issues/40186242
116+
// - https://github.com/react-dropzone/react-dropzone/issues/1397
117+
if (
118+
globalThis.isSecureContext &&
119+
typeof (item as any).getAsFileSystemHandle === "function"
120+
) {
113121
return (item as any).getAsFileSystemHandle().then(async (h: any) => {
114122
const file = await h.getFile();
115123
file.handle = h;

test-setup.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// NOTE: Let us test {isSecureContext}!
2+
Object.defineProperty(globalThis, "isSecureContext", {
3+
value: true,
4+
writable: true,
5+
enumerable: true,
6+
});

0 commit comments

Comments
 (0)