mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 23:18:47 +00:00
Compare commits
5 Commits
dylan/pyth
...
jarred/pro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fb5c502fd | ||
|
|
a04f6b8522 | ||
|
|
f17c71f3d6 | ||
|
|
acc258a210 | ||
|
|
cd26dacd59 |
@@ -278,7 +278,7 @@ pub const RuntimeTranspilerCache = struct {
|
||||
break :brk .{ .utf8 = utf8 };
|
||||
},
|
||||
.latin1 => brk: {
|
||||
var latin1, const bytes = bun.String.createUninitialized(.latin1, this.metadata.output_byte_length);
|
||||
var latin1, const bytes = try bun.String.createUninitialized(.latin1, this.metadata.output_byte_length);
|
||||
errdefer latin1.deref();
|
||||
const read_bytes = try file.preadAll(bytes, this.metadata.output_byte_offset);
|
||||
|
||||
@@ -295,7 +295,7 @@ pub const RuntimeTranspilerCache = struct {
|
||||
break :brk .{ .string = latin1 };
|
||||
},
|
||||
.utf16 => brk: {
|
||||
var string, const chars = bun.String.createUninitialized(.utf16, this.metadata.output_byte_length / 2);
|
||||
var string, const chars = try bun.String.createUninitialized(.utf16, this.metadata.output_byte_length / 2);
|
||||
errdefer string.deref();
|
||||
|
||||
const read_bytes = try file.preadAll(std.mem.sliceAsBytes(chars), this.metadata.output_byte_offset);
|
||||
|
||||
@@ -220,7 +220,7 @@ extern "C" JSC::EncodedJSValue BunString__toJS(JSC::JSGlobalObject* globalObject
|
||||
return JSValue::encode(Bun::toJS(globalObject, *bunString));
|
||||
}
|
||||
|
||||
extern "C" BunString BunString__fromUTF16Unitialized(size_t length)
|
||||
extern "C" BunString BunString__fromUTF16Uninitialized(size_t length)
|
||||
{
|
||||
ASSERT(length > 0);
|
||||
UChar* ptr;
|
||||
@@ -231,7 +231,7 @@ extern "C" BunString BunString__fromUTF16Unitialized(size_t length)
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = impl.leakRef() } };
|
||||
}
|
||||
|
||||
extern "C" BunString BunString__fromLatin1Unitialized(size_t length)
|
||||
extern "C" BunString BunString__fromLatin1Uninitialized(size_t length)
|
||||
{
|
||||
ASSERT(length > 0);
|
||||
LChar* ptr;
|
||||
|
||||
@@ -5801,11 +5801,9 @@ pub const NodeFS = struct {
|
||||
},
|
||||
},
|
||||
.string => brk: {
|
||||
const str = bun.SliceWithUnderlyingString.transcodeFromOwnedSlice(@constCast(ret.result.string), args.encoding);
|
||||
|
||||
if (str.underlying.tag == .Dead and str.utf8.len == 0) {
|
||||
const str = bun.SliceWithUnderlyingString.transcodeFromOwnedSlice(@constCast(ret.result.string), args.encoding) catch {
|
||||
return .{ .err = Syscall.Error.fromCode(.NOMEM, .read).withPathLike(args.path) };
|
||||
}
|
||||
};
|
||||
|
||||
break :brk .{ .result = .{ .string = str } };
|
||||
},
|
||||
|
||||
@@ -608,7 +608,10 @@ pub const Encoding = enum(u8) {
|
||||
.base64 => {
|
||||
var base64_buf: [std.base64.standard.Encoder.calcSize(max_size * 4)]u8 = undefined;
|
||||
const encoded_len = bun.base64.encode(&base64_buf, input);
|
||||
const encoded, const bytes = bun.String.createUninitialized(.latin1, encoded_len);
|
||||
const encoded, const bytes = bun.String.createUninitialized(.latin1, encoded_len) catch {
|
||||
globalObject.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
defer encoded.deref();
|
||||
@memcpy(@constCast(bytes), base64_buf[0..encoded_len]);
|
||||
return encoded.toJS(globalObject);
|
||||
|
||||
@@ -655,7 +655,10 @@ pub const Crypto = struct {
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
_: *JSC.CallFrame,
|
||||
) JSC.JSValue {
|
||||
const str, var bytes = bun.String.createUninitialized(.latin1, 36);
|
||||
const str, var bytes = bun.String.createUninitialized(.latin1, 36) catch {
|
||||
globalThis.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
defer str.deref();
|
||||
|
||||
const uuid = globalThis.bunVM().rareData().nextUUID();
|
||||
@@ -668,7 +671,10 @@ pub const Crypto = struct {
|
||||
_: *Crypto,
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
) JSC.JSValue {
|
||||
const str, var bytes = bun.String.createUninitialized(.latin1, 36);
|
||||
const str, var bytes = bun.String.createUninitialized(.latin1, 36) catch {
|
||||
globalThis.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
defer str.deref();
|
||||
|
||||
// randomUUID must have been called already many times before this kicks
|
||||
|
||||
@@ -35,6 +35,8 @@ const JSGlobalObject = JSC.JSGlobalObject;
|
||||
const VirtualMachine = JSC.VirtualMachine;
|
||||
const Task = @import("../javascript.zig").Task;
|
||||
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const picohttp = bun.picohttp;
|
||||
|
||||
pub const TextEncoder = struct {
|
||||
@@ -1104,7 +1106,8 @@ pub const Encoder = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toBunStringFromOwnedSlice(input: []u8, encoding: JSC.Node.Encoding) bun.String {
|
||||
/// Even in the error cases, the input bytes will be freed
|
||||
pub fn toBunStringFromOwnedSlice(input: []u8, encoding: JSC.Node.Encoding) OOM!bun.String {
|
||||
if (input.len == 0)
|
||||
return bun.String.empty;
|
||||
|
||||
@@ -1114,11 +1117,8 @@ pub const Encoder = struct {
|
||||
return bun.String.createExternalGloballyAllocated(.latin1, input);
|
||||
}
|
||||
|
||||
const str, const chars = bun.String.createUninitialized(.latin1, input.len);
|
||||
defer bun.default_allocator.free(input);
|
||||
if (str.tag == .Dead) {
|
||||
return str;
|
||||
}
|
||||
const str, const chars = try bun.String.createUninitialized(.latin1, input.len);
|
||||
strings.copyLatin1IntoASCII(chars, input);
|
||||
return str;
|
||||
},
|
||||
@@ -1126,9 +1126,9 @@ pub const Encoder = struct {
|
||||
return bun.String.createExternalGloballyAllocated(.latin1, input);
|
||||
},
|
||||
.buffer, .utf8 => {
|
||||
const converted = strings.toUTF16Alloc(bun.default_allocator, input, false, false) catch {
|
||||
const converted = strings.toUTF16Alloc(bun.default_allocator, input, false, false) catch |err| {
|
||||
bun.default_allocator.free(input);
|
||||
return bun.String.dead;
|
||||
return err;
|
||||
};
|
||||
|
||||
if (converted) |utf16| {
|
||||
@@ -1152,11 +1152,7 @@ pub const Encoder = struct {
|
||||
|
||||
.hex => {
|
||||
defer bun.default_allocator.free(input);
|
||||
const str, const chars = bun.String.createUninitialized(.latin1, input.len * 2);
|
||||
|
||||
if (str.tag == .Dead) {
|
||||
return str;
|
||||
}
|
||||
const str, const chars = try bun.String.createUninitialized(.latin1, input.len * 2);
|
||||
|
||||
const wrote = strings.encodeBytesToHex(chars, input);
|
||||
|
||||
@@ -1174,17 +1170,15 @@ pub const Encoder = struct {
|
||||
// appears inconsistent with Node.js.
|
||||
.base64url => {
|
||||
defer bun.default_allocator.free(input);
|
||||
const out, const chars = bun.String.createUninitialized(.latin1, bun.base64.urlSafeEncodeLen(input));
|
||||
if (out.tag != .Dead) {
|
||||
_ = bun.base64.encodeURLSafe(chars, input);
|
||||
}
|
||||
const out, const chars = try bun.String.createUninitialized(.latin1, bun.base64.urlSafeEncodeLen(input));
|
||||
_ = bun.base64.encodeURLSafe(chars, input);
|
||||
return out;
|
||||
},
|
||||
|
||||
.base64 => {
|
||||
defer bun.default_allocator.free(input);
|
||||
const to_len = bun.base64.encodeLen(input);
|
||||
const to = bun.default_allocator.alloc(u8, to_len) catch return bun.String.dead;
|
||||
const to = try bun.default_allocator.alloc(u8, to_len);
|
||||
const wrote = bun.base64.encode(to, input);
|
||||
return bun.String.createExternalGloballyAllocated(.latin1, to[0..wrote]);
|
||||
},
|
||||
@@ -1200,14 +1194,20 @@ pub const Encoder = struct {
|
||||
|
||||
switch (comptime encoding) {
|
||||
.ascii => {
|
||||
var str, const chars = bun.String.createUninitialized(.latin1, len);
|
||||
var str, const chars = bun.String.createUninitialized(.latin1, len) catch {
|
||||
global.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
defer str.deref();
|
||||
|
||||
strings.copyLatin1IntoASCII(chars, input);
|
||||
return str.toJS(global);
|
||||
},
|
||||
.latin1 => {
|
||||
var str, const chars = bun.String.createUninitialized(.latin1, len);
|
||||
var str, const chars = bun.String.createUninitialized(.latin1, len) catch {
|
||||
global.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
defer str.deref();
|
||||
|
||||
@memcpy(chars, input);
|
||||
@@ -1227,7 +1227,10 @@ pub const Encoder = struct {
|
||||
// Avoid incomplete characters
|
||||
if (len / 2 == 0) return ZigString.Empty.toJS(global);
|
||||
|
||||
var output, const chars = bun.String.createUninitialized(.utf16, len / 2);
|
||||
var output, const chars = bun.String.createUninitialized(.utf16, len / 2) catch {
|
||||
global.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
defer output.deref();
|
||||
var output_bytes = std.mem.sliceAsBytes(chars);
|
||||
output_bytes[output_bytes.len - 1] = 0;
|
||||
@@ -1237,7 +1240,10 @@ pub const Encoder = struct {
|
||||
},
|
||||
|
||||
.hex => {
|
||||
var str, const chars = bun.String.createUninitialized(.latin1, len * 2);
|
||||
var str, const chars = bun.String.createUninitialized(.latin1, len * 2) catch {
|
||||
global.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
defer str.deref();
|
||||
|
||||
const wrote = strings.encodeBytesToHex(chars, input);
|
||||
@@ -1246,7 +1252,10 @@ pub const Encoder = struct {
|
||||
},
|
||||
|
||||
.base64url => {
|
||||
var out, const chars = bun.String.createUninitialized(.latin1, bun.base64.urlSafeEncodeLen(input));
|
||||
var out, const chars = bun.String.createUninitialized(.latin1, bun.base64.urlSafeEncodeLen(input)) catch {
|
||||
global.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
defer out.deref();
|
||||
_ = bun.base64.encodeURLSafe(chars, input);
|
||||
return out.toJS(global);
|
||||
@@ -1254,7 +1263,11 @@ pub const Encoder = struct {
|
||||
|
||||
.base64 => {
|
||||
const to_len = bun.base64.encodeLen(input);
|
||||
var to = allocator.alloc(u8, to_len) catch return ZigString.init("Out of memory").toErrorInstance(global);
|
||||
var to = allocator.alloc(u8, to_len) catch {
|
||||
global.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
|
||||
const wrote = bun.base64.encode(to, input);
|
||||
return ZigString.init(to[0..wrote]).toExternalValue(global);
|
||||
},
|
||||
|
||||
@@ -474,7 +474,7 @@ pub const Request = struct {
|
||||
}
|
||||
|
||||
if (strings.isAllASCII(host) and strings.isAllASCII(req_url)) {
|
||||
this.url, const bytes = bun.String.createUninitialized(.latin1, url_bytelength);
|
||||
this.url, const bytes = try bun.String.createUninitialized(.latin1, url_bytelength);
|
||||
_ = std.fmt.bufPrint(bytes, "{s}{any}{s}", .{
|
||||
this.getProtocol(),
|
||||
fmt,
|
||||
@@ -484,13 +484,11 @@ pub const Request = struct {
|
||||
};
|
||||
} else {
|
||||
// slow path
|
||||
const temp_url = std.fmt.allocPrint(bun.default_allocator, "{s}{any}{s}", .{
|
||||
this.url = try bun.String.createFormat("{s}{any}{s}", .{
|
||||
this.getProtocol(),
|
||||
fmt,
|
||||
req_url,
|
||||
}) catch bun.outOfMemory();
|
||||
defer bun.default_allocator.free(temp_url);
|
||||
this.url = bun.String.createUTF8(temp_url);
|
||||
});
|
||||
}
|
||||
|
||||
const href = bun.JSC.URL.hrefFromString(this.url);
|
||||
|
||||
@@ -2517,7 +2517,10 @@ pub const E = struct {
|
||||
}
|
||||
|
||||
if (s.is_utf16) {
|
||||
var out, const chars = bun.String.createUninitialized(.utf16, s.len());
|
||||
var out, const chars = bun.String.createUninitialized(.utf16, s.len()) catch {
|
||||
globalObject.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
defer out.deref();
|
||||
@memcpy(chars, s.slice16());
|
||||
return out.toJS(globalObject);
|
||||
@@ -2529,7 +2532,10 @@ pub const E = struct {
|
||||
const decoded = js_lexer.decodeStringLiteralEscapeSequencesToUTF16(s.slice(allocator), allocator) catch unreachable;
|
||||
defer allocator.free(decoded);
|
||||
|
||||
var out, const chars = bun.String.createUninitialized(.utf16, decoded.len);
|
||||
var out, const chars = bun.String.createUninitialized(.utf16, decoded.len) catch {
|
||||
globalObject.throwOutOfMemory();
|
||||
return .zero;
|
||||
};
|
||||
defer out.deref();
|
||||
@memcpy(chars, decoded);
|
||||
|
||||
|
||||
@@ -363,7 +363,9 @@ pub export fn napi_create_string_latin1(env: napi_env, str: ?[*]const u8, length
|
||||
return .ok;
|
||||
}
|
||||
|
||||
var string, const bytes = bun.String.createUninitialized(.latin1, slice.len);
|
||||
var string, const bytes = bun.String.createUninitialized(.latin1, slice.len) catch {
|
||||
return .generic_failure;
|
||||
};
|
||||
defer string.deref();
|
||||
|
||||
@memcpy(bytes, slice);
|
||||
@@ -424,7 +426,9 @@ pub export fn napi_create_string_utf16(env: napi_env, str: ?[*]const char16_t, l
|
||||
result.set(env, bun.String.empty.toJS(env));
|
||||
}
|
||||
|
||||
var string, const chars = bun.String.createUninitialized(.utf16, slice.len);
|
||||
var string, const chars = bun.String.createUninitialized(.utf16, slice.len) catch {
|
||||
return .generic_failure;
|
||||
};
|
||||
defer string.deref();
|
||||
|
||||
@memcpy(chars, slice);
|
||||
|
||||
@@ -271,6 +271,7 @@ pub const StringImplAllocator = struct {
|
||||
pub const Tag = enum(u8) {
|
||||
/// String is not valid. Observed on some failed operations.
|
||||
/// To prevent crashes, this value acts similarly to .Empty (such as length = 0)
|
||||
/// Prefer `error.OutOfMemory` instead of this value.
|
||||
Dead = 0,
|
||||
/// String is backed by a WTF::StringImpl from JavaScriptCore.
|
||||
/// Can be in either `latin1` or `utf16le` encodings.
|
||||
@@ -314,8 +315,8 @@ pub const String = extern struct {
|
||||
extern fn BunString__fromBytes(bytes: [*]const u8, len: usize) String;
|
||||
extern fn BunString__fromUTF16(bytes: [*]const u16, len: usize) String;
|
||||
extern fn BunString__fromUTF16ToLatin1(bytes: [*]const u16, len: usize) String;
|
||||
extern fn BunString__fromLatin1Unitialized(len: usize) String;
|
||||
extern fn BunString__fromUTF16Unitialized(len: usize) String;
|
||||
extern fn BunString__fromLatin1Uninitialized(len: usize) String;
|
||||
extern fn BunString__fromUTF16Uninitialized(len: usize) String;
|
||||
|
||||
pub fn ascii(bytes: []const u8) String {
|
||||
return String{ .tag = .ZigString, .value = .{ .ZigString = ZigString.init(bytes) } };
|
||||
@@ -369,9 +370,13 @@ pub const String = extern struct {
|
||||
return createUTF8(utf8_slice);
|
||||
}
|
||||
|
||||
fn createUninitializedLatin1(len: usize) struct { String, []u8 } {
|
||||
fn createUninitializedLatin1(len: usize) !struct { String, []u8 } {
|
||||
bun.assert(len > 0);
|
||||
const string = BunString__fromLatin1Unitialized(len);
|
||||
const string = BunString__fromLatin1Uninitialized(len);
|
||||
if (string.tag == .Dead) {
|
||||
return error.OutOfMemory;
|
||||
}
|
||||
|
||||
const wtf = string.value.WTFStringImpl;
|
||||
return .{
|
||||
string,
|
||||
@@ -379,9 +384,13 @@ pub const String = extern struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn createUninitializedUTF16(len: usize) struct { String, []u16 } {
|
||||
fn createUninitializedUTF16(len: usize) !struct { String, []u16 } {
|
||||
bun.assert(len > 0);
|
||||
const string = BunString__fromUTF16Unitialized(len);
|
||||
const string = BunString__fromUTF16Uninitialized(len);
|
||||
if (string.tag == .Dead) {
|
||||
return error.OutOfMemory;
|
||||
}
|
||||
|
||||
const wtf = string.value.WTFStringImpl;
|
||||
return .{
|
||||
string,
|
||||
@@ -406,12 +415,10 @@ pub const String = extern struct {
|
||||
///
|
||||
/// This is not allowed on zero-length strings, in this case you should
|
||||
/// check earlier and use String.empty in that case.
|
||||
///
|
||||
/// If the length is too large, this will return a dead string.
|
||||
pub fn createUninitialized(
|
||||
comptime kind: WTFStringEncoding,
|
||||
len: usize,
|
||||
) struct { String, [](kind.Byte()) } {
|
||||
) OOM!struct { String, [](kind.Byte()) } {
|
||||
bun.assert(len > 0);
|
||||
return switch (comptime kind) {
|
||||
.latin1 => createUninitializedLatin1(len),
|
||||
@@ -478,10 +485,8 @@ pub const String = extern struct {
|
||||
}
|
||||
|
||||
if (this.isUTF16()) {
|
||||
const new, const bytes = createUninitialized(.utf16, this.length());
|
||||
if (new.tag != .Dead) {
|
||||
@memcpy(bytes, this.value.ZigString.utf16Slice());
|
||||
}
|
||||
const new, const bytes = createUninitialized(.utf16, this.length()) catch bun.outOfMemory();
|
||||
@memcpy(bytes, this.value.ZigString.utf16Slice());
|
||||
return new;
|
||||
}
|
||||
|
||||
@@ -1366,7 +1371,7 @@ pub const SliceWithUnderlyingString = struct {
|
||||
/// Transcode a byte array to an encoded String, avoiding unnecessary copies.
|
||||
///
|
||||
/// owned_input_bytes ownership is transferred to this function
|
||||
pub fn transcodeFromOwnedSlice(owned_input_bytes: []u8, encoding: JSC.Node.Encoding) SliceWithUnderlyingString {
|
||||
pub fn transcodeFromOwnedSlice(owned_input_bytes: []u8, encoding: JSC.Node.Encoding) OOM!SliceWithUnderlyingString {
|
||||
if (owned_input_bytes.len == 0) {
|
||||
return .{
|
||||
.utf8 = ZigString.Slice.empty,
|
||||
@@ -1375,7 +1380,7 @@ pub const SliceWithUnderlyingString = struct {
|
||||
}
|
||||
|
||||
return .{
|
||||
.underlying = JSC.WebCore.Encoder.toBunStringFromOwnedSlice(owned_input_bytes, encoding),
|
||||
.underlying = try JSC.WebCore.Encoder.toBunStringFromOwnedSlice(owned_input_bytes, encoding),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user