aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/webcore/blob.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-05-31 19:17:01 -0700
committerGravatar GitHub <noreply@github.com> 2023-05-31 19:17:01 -0700
commitcb0f76aa73f6b85667b57015a77ac39d9c78aa0b (patch)
tree949bcc466b3afbbb69a070d35d2b814f0e66be40 /src/bun.js/webcore/blob.zig
parent79d7b2075e63f79ec6d1d2a904178969eb701f0b (diff)
parent110d0752f333e4c32c9226e4a94e93f18837f9c7 (diff)
downloadbun-cb0f76aa73f6b85667b57015a77ac39d9c78aa0b.tar.gz
bun-cb0f76aa73f6b85667b57015a77ac39d9c78aa0b.tar.zst
bun-cb0f76aa73f6b85667b57015a77ac39d9c78aa0b.zip
Merge branch 'main' into jarred/port
Diffstat (limited to 'src/bun.js/webcore/blob.zig')
-rw-r--r--src/bun.js/webcore/blob.zig49
1 files changed, 46 insertions, 3 deletions
diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig
index 591150e12..a5d3c968d 100644
--- a/src/bun.js/webcore/blob.zig
+++ b/src/bun.js/webcore/blob.zig
@@ -85,6 +85,7 @@ pub const Blob = struct {
store: ?*Store = null,
content_type: string = "",
content_type_allocated: bool = false,
+ content_type_was_set: bool = false,
/// JavaScriptCore strings are either latin1 or UTF-16
/// When UTF-16, they're nearly always due to non-ascii characters
@@ -111,6 +112,10 @@ pub const Blob = struct {
return bun.FormData.AsyncFormData.init(this.allocator orelse bun.default_allocator, encoding) catch unreachable;
}
+ pub fn hasContentTypeFromUser(this: *const Blob) bool {
+ return this.content_type_was_set or (this.store != null and this.store.?.data == .file);
+ }
+
const FormDataContext = struct {
allocator: std.mem.Allocator,
joiner: StringJoiner,
@@ -228,6 +233,7 @@ pub const Blob = struct {
var blob = Blob.initWithStore(store, globalThis);
blob.content_type = store.mime_type.value;
+ blob.content_type_was_set = true;
return blob;
}
@@ -268,6 +274,7 @@ pub const Blob = struct {
var blob = Blob.initWithStore(store, globalThis);
blob.content_type = std.fmt.allocPrint(allocator, "multipart/form-data; boundary=\"{s}\"", .{boundary}) catch unreachable;
blob.content_type_allocated = true;
+ blob.content_type_was_set = true;
return blob;
}
@@ -288,7 +295,7 @@ pub const Blob = struct {
export fn Blob__dupe(ptr: *anyopaque) *Blob {
var this = bun.cast(*Blob, ptr);
var new = bun.default_allocator.create(Blob) catch unreachable;
- new.* = this.dupe();
+ new.* = this.dupeWithContentType(true);
new.allocator = bun.default_allocator;
return new;
}
@@ -2527,6 +2534,7 @@ pub const Blob = struct {
blob.content_type = content_type;
blob.content_type_allocated = content_type_was_allocated;
+ blob.content_type_was_set = this.content_type_was_set or content_type_was_allocated;
var blob_ = allocator.create(Blob) catch unreachable;
blob_.* = blob;
@@ -2548,13 +2556,13 @@ pub const Blob = struct {
) callconv(.C) JSValue {
if (this.content_type.len > 0) {
if (this.content_type_allocated) {
- return ZigString.init(this.content_type).toValue(globalThis);
+ return ZigString.init(this.content_type).toValueGC(globalThis);
}
return ZigString.init(this.content_type).toValueGC(globalThis);
}
if (this.store) |store| {
- return ZigString.init(store.mime_type.value).toValue(globalThis);
+ return ZigString.init(store.mime_type.value).toValueGC(globalThis);
}
return ZigString.Empty.toValue(globalThis);
@@ -2754,6 +2762,8 @@ pub const Blob = struct {
if (!strings.isAllASCII(slice)) {
break :inner;
}
+ blob.content_type_was_set = true;
+
if (globalThis.bunVM().mimeType(slice)) |mime| {
blob.content_type = mime.value;
break :inner;
@@ -2769,6 +2779,7 @@ pub const Blob = struct {
if (blob.content_type.len == 0) {
blob.content_type = "";
+ blob.content_type_was_set = false;
}
},
}
@@ -2870,8 +2881,33 @@ pub const Blob = struct {
/// This creates a new view
/// and increment the reference count
pub fn dupe(this: *const Blob) Blob {
+ return this.dupeWithContentType(false);
+ }
+
+ pub fn dupeWithContentType(this: *const Blob, include_content_type: bool) Blob {
if (this.store != null) this.store.?.ref();
var duped = this.*;
+ if (duped.content_type_allocated and duped.allocator != null and !include_content_type) {
+
+ // for now, we just want to avoid a use-after-free here
+ if (JSC.VirtualMachine.get().mimeType(duped.content_type)) |mime| {
+ duped.content_type = mime.value;
+ } else {
+ // TODO: fix this
+ // this is a bug.
+ // it means whenever
+ duped.content_type = "";
+ }
+
+ duped.content_type_allocated = false;
+ duped.content_type_was_set = false;
+ if (this.content_type_was_set) {
+ duped.content_type_was_set = duped.content_type.len > 0;
+ }
+ } 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 @panic("Out of memory");
+ }
+
duped.allocator = null;
return duped;
}
@@ -3477,6 +3513,13 @@ pub const AnyBlob = union(enum) {
// InlineBlob: InlineBlob,
InternalBlob: InternalBlob,
+ pub fn hasContentTypeFromUser(this: AnyBlob) bool {
+ return switch (this) {
+ .Blob => this.Blob.hasContentTypeFromUser(),
+ .InternalBlob => false,
+ };
+ }
+
pub fn toJSON(this: *AnyBlob, global: *JSGlobalObject, comptime lifetime: JSC.WebCore.Lifetime) JSValue {
switch (this.*) {
.Blob => return this.Blob.toJSON(global, lifetime),