Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/bun.js/webcore/FileReader.zig
Original file line number Diff line number Diff line change
Expand Up @@ -320,14 +320,18 @@ pub fn onReadChunk(this: *@This(), init_buf: []const u8, state: bun.io.ReadState

if (buf.len > 0) {
if (this.max_size) |max_size| {
if (this.total_readed >= max_size) return false;
if (this.total_readed >= max_size) {
close = true;
hasMore = false;
return false;
}
const len = @min(max_size - this.total_readed, buf.len);
if (buf.len > len) {
buf = buf[0..len];
}
this.total_readed += len;

if (buf.len == 0) {
if (this.total_readed >= max_size) {
close = true;
hasMore = false;
}
Expand Down
41 changes: 41 additions & 0 deletions test/regression/issue/18192.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// https://github.com/oven-sh/bun/issues/18192
// Bun.file().slice().stream() should not hang for files larger than 640KB

import { expect, test } from "bun:test";
import { tempDir } from "harness";
import { join } from "path";

test("Bun.file().slice().stream() should not hang for large files", async () => {
using tmpbase = tempDir("issue-18192", {});
const path = join(tmpbase, "large-file.bin");

const size = 1024 * 1024; // 1mb file
await Bun.write(path, new Uint8Array(size).fill(69));

const file = Bun.file(path);

// tiny slice
{
const sliced = file.slice(0, 1);
const bytes = await new Response(sliced.stream()).bytes();
expect(bytes.length).toBe(1);
expect(bytes).toEqual(new Uint8Array(1).fill(69));
}

// zero length slice
{
const sliced = file.slice(0, 0);
const bytes = await new Response(sliced.stream()).bytes();
expect(bytes.length).toBe(0);
}

// somewhere in the middle slice
{
const midStart = 500 * 1024;
const midEnd = midStart + 10;
const sliced = file.slice(midStart, midEnd);
const bytes = await new Response(sliced.stream()).bytes();
expect(bytes.length).toBe(10);
expect(bytes).toEqual(new Uint8Array(10).fill(69));
}
});
24 changes: 24 additions & 0 deletions test/regression/issue/21175.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// https://github.com/oven-sh/bun/issues/21175
// Bun.file().slice().stream() should not hang when consumed via iterator
import { expect, test } from "bun:test";
import { tempDir } from "harness";
import { join } from "path";

test("Bun.file().slice().stream() iterator consumption", async () => {
using tmpbase = tempDir("issue-21175", {});
const path = join(tmpbase, "large-file.bin");

const size = 1024 * 1024; // 1mb file
await Bun.write(path, new Uint8Array(size).fill(69));
const file = Bun.file(path);

const sliced = file.slice(0, 16384);
const stream = sliced.stream();

let totalLen = 0;
// @ts-expect-error: ReadableStream is async iterable
for await (const chunk of stream) {
totalLen += chunk.length;
}
expect(totalLen).toBe(16384);
});