aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-03-07 22:16:55 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-03-07 22:16:55 -0800
commit88ad5ed73cc6e6e0f006905a7e161a942a8ea277 (patch)
tree614581917af0db22e8898bc2dcc467d5408fffc5
parent4d3eefa45f0c5adcb278a81f6f536227ffac9550 (diff)
downloadbun-88ad5ed73cc6e6e0f006905a7e161a942a8ea277.tar.gz
bun-88ad5ed73cc6e6e0f006905a7e161a942a8ea277.tar.zst
bun-88ad5ed73cc6e6e0f006905a7e161a942a8ea277.zip
Make `Blob.prototype.type` more spec compliant
-rw-r--r--src/bun.js/bindings/bindings.zig4
-rw-r--r--src/bun.js/webcore/blob.zig28
-rw-r--r--test/js/web/fetch/blob.test.ts17
3 files changed, 41 insertions, 8 deletions
diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig
index d21250567..4df5e1996 100644
--- a/src/bun.js/bindings/bindings.zig
+++ b/src/bun.js/bindings/bindings.zig
@@ -2276,6 +2276,10 @@ pub const JSGlobalObject = extern struct {
return this.bunVM().allocator;
}
+ pub fn throwOutOfMemory(this: *JSGlobalObject) void {
+ this.throwValue(this.createErrorInstance("Out of memory", .{}));
+ }
+
pub fn throwInvalidArguments(
this: *JSGlobalObject,
comptime fmt: string,
diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig
index c95aad48e..a593bfe05 100644
--- a/src/bun.js/webcore/blob.zig
+++ b/src/bun.js/webcore/blob.zig
@@ -2507,19 +2507,31 @@ pub const Blob = struct {
globalThis: *JSC.JSGlobalObject,
value: JSC.JSValue,
) callconv(.C) bool {
- var zig_str = value.getZigString(globalThis);
- if (zig_str.is16Bit())
- return false;
+ const zig_str = if (value.isString())
+ value.getZigString(globalThis)
+ else
+ ZigString.Empty;
- var slice = zig_str.trimmedSlice();
- if (strings.eql(slice, this.content_type))
+ if (zig_str.eql(ZigString.init(this.content_type))) {
return true;
+ }
const prev_content_type = this.content_type;
{
- defer if (this.content_type_allocated) bun.default_allocator.free(prev_content_type);
- var content_type_buf = globalThis.allocator().alloc(u8, slice.len) catch unreachable;
- this.content_type = strings.copyLowercase(slice, content_type_buf);
+ var slicer = zig_str.toSlice(bun.default_allocator);
+ defer slicer.deinit();
+ const allocated = this.content_type_allocated;
+ defer if (allocated) bun.default_allocator.free(prev_content_type);
+ if (globalThis.bunVM().mimeType(slicer.slice())) |mime| {
+ this.content_type = mime.value;
+ this.content_type_allocated = false;
+ return true;
+ }
+ var content_type_buf = globalThis.allocator().alloc(u8, slicer.len) catch {
+ globalThis.throwOutOfMemory();
+ return false;
+ };
+ this.content_type = strings.copyLowercase(slicer.slice(), content_type_buf);
}
this.content_type_allocated = true;
diff --git a/test/js/web/fetch/blob.test.ts b/test/js/web/fetch/blob.test.ts
index ba44f8c1b..51b9c0ea8 100644
--- a/test/js/web/fetch/blob.test.ts
+++ b/test/js/web/fetch/blob.test.ts
@@ -28,6 +28,23 @@ test("Blob.slice", () => {
expect(blob.slice("text/plain;charset=utf-8").type).toBe("text/plain;charset=utf-8");
});
+test("Blob.prototype.type setter", () => {
+ var blob = new Blob(["Bun", "Foo"], { type: "text/foo" });
+ expect(blob.type).toBe("text/foo");
+ blob.type = "text/bar";
+ expect(blob.type).toBe("text/bar");
+ blob.type = "text/baz";
+ expect(blob.type).toBe("text/baz");
+ blob.type = "text/baz; charset=utf-8";
+ expect(blob.type).toBe("text/baz; charset=utf-8");
+ // @ts-expect-error
+ blob.type = NaN;
+ expect(blob.type).toBe("");
+ // @ts-expect-error
+ blob.type = Symbol();
+ expect(blob.type).toBe("");
+});
+
test("new Blob", () => {
var blob = new Blob(["Bun", "Foo"], { type: "text/foo" });
expect(blob.size).toBe(6);