Skip to content

Commit

Permalink
Fixes #14918 (#14921)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner authored and 190n committed Nov 2, 2024
1 parent b5ed0f0 commit 664c080
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/bun.js/webcore/blob.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1542,7 +1542,7 @@ pub const Blob = struct {
}
}

this.reported_estimated_size = size + (this.content_type.len * @intFromBool(this.content_type_allocated));
this.reported_estimated_size = size + (this.content_type.len * @intFromBool(this.content_type_allocated)) + this.name.byteSlice().len;
}

pub fn estimatedSize(this: *Blob) usize {
Expand Down Expand Up @@ -3784,7 +3784,7 @@ pub const Blob = struct {
return true;
}
if (value.isString()) {
this.name.deref();
const old_name = this.name;

this.name = bun.String.tryFromJS(value, globalThis) orelse {
// Handle allocation failure.
Expand All @@ -3793,6 +3793,7 @@ pub const Blob = struct {
};
// We don't need to increment the reference count since tryFromJS already did it.
Blob.nameSetCached(jsThis, globalThis, value);
old_name.deref();
return true;
}
return false;
Expand Down Expand Up @@ -4181,6 +4182,7 @@ pub const Blob = struct {
} else if (duped.content_type_allocated and duped.allocator != null and include_content_type) {
duped.content_type = bun.default_allocator.dupe(u8, this.content_type) catch bun.outOfMemory();
}
duped.name = duped.name.dupeRef();

duped.allocator = null;
return duped;
Expand Down
25 changes: 25 additions & 0 deletions test/js/web/html/FormData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,4 +620,29 @@ describe("FormData", () => {
expect(fileSlice.size).toBe(result.size);
});
});

// The minimum repro for this was to not call the .name and .type getter on the Blob
// But the crux of the issue is that we called dupe() on the Blob, without also incrementing the reference count of the name string.
// https://github.com/oven-sh/bun/issues/14918
it("should increment reference count of the name string on Blob", async () => {
const buffer = new File([Buffer.from(Buffer.alloc(48 * 1024, "abcdefh").toString("base64"), "base64")], "ok.jpg");
function test() {
let file = new File([buffer], "ok.jpg");
file.name;
file.type;

let formData = new FormData();
formData.append("foo", file);
formData.get("foo");
formData.get("foo")!.name;
formData.get("foo")!.type;
return formData;
}
for (let i = 0; i < 100000; i++) {
test();
if (i % 5000 === 0) {
Bun.gc();
}
}
});
});

0 comments on commit 664c080

Please sign in to comment.