Skip to content

Commit

Permalink
fix(ext/fs): truncate files when a ReadableStream is passed to writeF…
Browse files Browse the repository at this point in the history
…ile (denoland#23330)

Closes denoland#19697. This fixes a bug where the writeFile API can create
partially-overwritten files which may lead to invalid / corrupt files or
data leakage. It also aligns the behavior of writing a ReadableStream
and writing a Uint8Array to the disk.
  • Loading branch information
char committed May 27, 2024
1 parent 35e5159 commit 506c275
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
1 change: 1 addition & 0 deletions ext/fs/30_fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,7 @@ async function writeFile(
append: options.append ?? false,
create: options.create ?? true,
createNew: options.createNew ?? false,
truncate: !(options.append ?? false),
write: true,
});
await data.pipeTo(file.writable, {
Expand Down
18 changes: 18 additions & 0 deletions tests/unit/write_file_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,3 +425,21 @@ Deno.test(
assertEquals(Deno.readFileSync(filename), new Uint8Array([1, 2]));
},
);

Deno.test(
{ permissions: { read: true, write: true } },
async function overwriteFileWithStream() {
const filename = Deno.makeTempDirSync() + "/test.txt";
await Deno.writeFile(filename, new Uint8Array([1, 2, 3, 4]));

const stream = new ReadableStream({
pull(controller) {
controller.enqueue(new Uint8Array([1]));
controller.enqueue(new Uint8Array([2]));
controller.close();
},
});
await Deno.writeFile(filename, stream);
assertEquals(Deno.readFileSync(filename), new Uint8Array([1, 2]));
},
);

0 comments on commit 506c275

Please sign in to comment.