aboutsummaryrefslogtreecommitdiff
path: root/src/resolver/data_url.zig
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/resolver/data_url.zig33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/resolver/data_url.zig b/src/resolver/data_url.zig
index dd31605d9..f2a042c4f 100644
--- a/src/resolver/data_url.zig
+++ b/src/resolver/data_url.zig
@@ -34,7 +34,7 @@ pub const PercentEncoding = struct {
if (comptime Environment.allow_assert) std.debug.assert(str.len > 0);
return switch (str[0]) {
'a'...'z', 'A'...'Z', '0'...'9', '-', '.', '_', '~', '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '@' => true,
- '%' => str.len > 3 and isHex(str[1]) and isHex(str[2]),
+ '%' => str.len >= 3 and isHex(str[1]) and isHex(str[2]),
else => false,
};
}
@@ -53,7 +53,7 @@ pub const PercentEncoding = struct {
}
if (ret == null) {
ret = try allocator.alloc(u8, path.len);
- bun.copy(u8, ret, path[0..i]);
+ bun.copy(u8, ret.?, path[0..i]);
ret_index = i;
}
@@ -71,22 +71,28 @@ pub const PercentEncoding = struct {
}
}
- if (ret) |some| return allocator.shrink(some, ret_index);
+ if (ret) |some| return some[0..ret_index];
return null;
}
};
pub const DataURL = struct {
+ url: bun.String = bun.String.empty,
mime_type: string,
data: string,
is_base64: bool = false,
- pub fn parse(url: string) ?DataURL {
+ pub fn parse(url: string) !?DataURL {
if (!strings.startsWith(url, "data:")) {
return null;
}
- const comma = strings.indexOfChar(url, ',') orelse return null;
+ var result = try parseWithoutCheck(url);
+ return result;
+ }
+
+ pub fn parseWithoutCheck(url: string) !DataURL {
+ const comma = strings.indexOfChar(url, ',') orelse return error.InvalidDataURL;
var parsed = DataURL{
.mime_type = url["data:".len..comma],
@@ -102,6 +108,21 @@ pub const DataURL = struct {
}
pub fn decodeMimeType(d: DataURL) bun.HTTP.MimeType {
- return bun.HTTP.MimeType.init(d.mime_type);
+ return bun.HTTP.MimeType.init(d.mime_type, null, null);
+ }
+
+ pub fn decodeData(url: DataURL, allocator: std.mem.Allocator) ![]u8 {
+ const percent_decoded = PercentEncoding.decode(allocator, url.data) catch url.data orelse url.data;
+ if (url.is_base64) {
+ const len = bun.base64.decodeLen(percent_decoded);
+ var buf = try allocator.alloc(u8, len);
+ const result = bun.base64.decode(buf, percent_decoded);
+ if (result.fail or result.written != len) {
+ return error.Base64DecodeError;
+ }
+ return buf;
+ }
+
+ return allocator.dupe(u8, percent_decoded);
}
};