Skip to content

Commit

Permalink
Clean up some error handling code (#15368)
Browse files Browse the repository at this point in the history
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
  • Loading branch information
Jarred-Sumner and dylan-conway authored Nov 25, 2024
1 parent b19f13f commit 8ca0eb8
Show file tree
Hide file tree
Showing 11 changed files with 977 additions and 163 deletions.
39 changes: 23 additions & 16 deletions src/bun.js/api/bun/h2_frame_parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3353,24 +3353,27 @@ pub const H2FrameParser = struct {

if (this.isServer) {
if (!ValidPseudoHeaders.has(name)) {
const exception = JSC.toTypeError(.ERR_HTTP2_INVALID_PSEUDOHEADER, "\"{s}\" is an invalid pseudoheader or is used incorrectly", .{name}, globalObject);
globalObject.throwValue(exception);
if (!globalObject.hasException()) {
globalObject.ERR_HTTP2_INVALID_PSEUDOHEADER("\"{s}\" is an invalid pseudoheader or is used incorrectly", .{name}).throw();
}
return .zero;
}
} else {
if (!ValidRequestPseudoHeaders.has(name)) {
const exception = JSC.toTypeError(.ERR_HTTP2_INVALID_PSEUDOHEADER, "\"{s}\" is an invalid pseudoheader or is used incorrectly", .{name}, globalObject);
globalObject.throwValue(exception);
if (!globalObject.hasException()) {
globalObject.ERR_HTTP2_INVALID_PSEUDOHEADER("\"{s}\" is an invalid pseudoheader or is used incorrectly", .{name}).throw();
}
return .zero;
}
}
} else if (ignore_pseudo_headers == 0) {
continue;
}

var js_value = try headers_arg.getTruthy(globalObject, name) orelse {
const exception = JSC.toTypeError(.ERR_HTTP2_INVALID_HEADER_VALUE, "Invalid value for header \"{s}\"", .{name}, globalObject);
globalObject.throwValue(exception);
const js_value: JSC.JSValue = try headers_arg.get(globalObject, name) orelse {
if (!globalObject.hasException()) {
globalObject.ERR_HTTP2_INVALID_HEADER_VALUE("Invalid value for header \"{s}\"", .{name}).throw();
}
return .zero;
};

Expand All @@ -3380,21 +3383,24 @@ pub const H2FrameParser = struct {
var value_iter = js_value.arrayIterator(globalObject);

if (SingleValueHeaders.has(name) and value_iter.len > 1) {
const exception = JSC.toTypeError(.ERR_HTTP2_INVALID_HEADER_VALUE, "Header field \"{s}\" must only have a single value", .{name}, globalObject);
globalObject.throwValue(exception);
if (!globalObject.hasException()) {
globalObject.ERR_HTTP2_INVALID_HEADER_VALUE("Header field \"{s}\" must only have a single value", .{name}).throw();
}
return .zero;
}

while (value_iter.next()) |item| {
if (item.isEmptyOrUndefinedOrNull()) {
const exception = JSC.toTypeError(.ERR_HTTP2_INVALID_HEADER_VALUE, "Invalid value for header \"{s}\"", .{name}, globalObject);
globalObject.throwValue(exception);
if (!globalObject.hasException()) {
globalObject.ERR_HTTP2_INVALID_HEADER_VALUE("Invalid value for header \"{s}\"", .{name}).throw();
}
return .zero;
}

const value_str = item.toStringOrNull(globalObject) orelse {
const exception = JSC.toTypeError(.ERR_HTTP2_INVALID_HEADER_VALUE, "Invalid value for header \"{s}\"", .{name}, globalObject);
globalObject.throwValue(exception);
if (!globalObject.hasException()) {
globalObject.ERR_HTTP2_INVALID_HEADER_VALUE("Invalid value for header \"{s}\"", .{name}).throw();
}
return .zero;
};

Expand All @@ -3417,11 +3423,12 @@ pub const H2FrameParser = struct {
return .undefined;
};
}
} else {
} else if (!js_value.isEmptyOrUndefinedOrNull()) {
log("single header {s}", .{name});
const value_str = js_value.toStringOrNull(globalObject) orelse {
const exception = JSC.toTypeError(.ERR_HTTP2_INVALID_HEADER_VALUE, "Invalid value for header \"{s}\"", .{name}, globalObject);
globalObject.throwValue(exception);
if (!globalObject.hasException()) {
globalObject.ERR_HTTP2_INVALID_HEADER_VALUE("Invalid value for header \"{s}\"", .{name}).throw();
}
return .zero;
};

Expand Down
39 changes: 24 additions & 15 deletions src/bun.js/api/bun/socket.zig
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ pub const SocketConfig = struct {

pub fn fromJS(vm: *JSC.VirtualMachine, opts: JSC.JSValue, globalObject: *JSC.JSGlobalObject) bun.JSError!SocketConfig {
var hostname_or_unix: JSC.ZigString.Slice = JSC.ZigString.Slice.empty;
errdefer hostname_or_unix.deinit();
var port: ?u16 = null;
var exclusive = false;
var allowHalfOpen = false;
Expand All @@ -332,23 +333,31 @@ pub const SocketConfig = struct {
}
}

errdefer {
if (ssl != null) {
ssl.?.deinit();
}
}

hostname_or_unix: {
if (try opts.getTruthy(globalObject, "fd")) |fd_| {
if (fd_.isNumber()) {
break :hostname_or_unix;
}
}

if (try opts.getTruthy(globalObject, "unix")) |unix_socket| {
if (!unix_socket.isString()) {
return globalObject.throwInvalidArguments("Expected \"unix\" to be a string", .{});
}
if (try opts.getStringish(globalObject, "unix")) |unix_socket| {
defer unix_socket.deref();

hostname_or_unix = unix_socket.getZigString(globalObject).toSlice(bun.default_allocator);
hostname_or_unix = try unix_socket.toUTF8WithoutRef(bun.default_allocator).cloneIfNeeded(bun.default_allocator);

if (strings.hasPrefixComptime(hostname_or_unix.slice(), "file://") or strings.hasPrefixComptime(hostname_or_unix.slice(), "unix://") or strings.hasPrefixComptime(hostname_or_unix.slice(), "sock://")) {
hostname_or_unix.ptr += 7;
hostname_or_unix.len -|= 7;
// The memory allocator relies on the pointer address to
// free it, so if we simply moved the pointer up it would
// cause an issue when freeing it later.
const moved_bytes = try bun.default_allocator.dupeZ(u8, hostname_or_unix.slice()[7..]);
hostname_or_unix.deinit();
hostname_or_unix = ZigString.Slice.init(bun.default_allocator, moved_bytes);
}

if (hostname_or_unix.len > 0) {
Expand All @@ -363,20 +372,21 @@ pub const SocketConfig = struct {
allowHalfOpen = true;
}

if (try opts.getTruthy(globalObject, "hostname") orelse try opts.getTruthy(globalObject, "host")) |hostname| {
if (!hostname.isString()) {
return globalObject.throwInvalidArguments("Expected \"hostname\" to be a string", .{});
}
if (try opts.getStringish(globalObject, "hostname") orelse try opts.getStringish(globalObject, "host")) |hostname| {
defer hostname.deref();

var port_value = try opts.get(globalObject, "port") orelse JSValue.zero;
hostname_or_unix = hostname.getZigString(globalObject).toSlice(bun.default_allocator);
hostname_or_unix = try hostname.toUTF8WithoutRef(bun.default_allocator).cloneIfNeeded(bun.default_allocator);

if (port_value.isEmptyOrUndefinedOrNull() and hostname_or_unix.len > 0) {
const parsed_url = bun.URL.parse(hostname_or_unix.slice());
if (parsed_url.getPort()) |port_num| {
port_value = JSValue.jsNumber(port_num);
hostname_or_unix.ptr = parsed_url.hostname.ptr;
hostname_or_unix.len = @as(u32, @truncate(parsed_url.hostname.len));
if (parsed_url.hostname.len > 0) {
const moved_bytes = try bun.default_allocator.dupeZ(u8, parsed_url.hostname);
hostname_or_unix.deinit();
hostname_or_unix = ZigString.Slice.init(bun.default_allocator, moved_bytes);
}
}
}

Expand Down Expand Up @@ -410,7 +420,6 @@ pub const SocketConfig = struct {

return globalObject.throwInvalidArguments("Expected either \"hostname\" or \"unix\"", .{});
}
errdefer hostname_or_unix.deinit();

var handlers = try Handlers.fromJS(globalObject, try opts.get(globalObject, "socket") orelse JSValue.zero);

Expand Down
16 changes: 6 additions & 10 deletions src/bun.js/api/server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1304,11 +1304,9 @@ pub const ServerConfig = struct {
}
if (global.hasException()) return error.JSError;

if (try arg.getTruthy(global, "hostname") orelse try arg.getTruthy(global, "host")) |host| {
const host_str = host.toSlice(
global,
bun.default_allocator,
);
if (try arg.getStringish(global, "hostname") orelse try arg.getStringish(global, "host")) |host| {
defer host.deref();
const host_str = host.toUTF8(bun.default_allocator);
defer host_str.deinit();

if (host_str.len > 0) {
Expand All @@ -1318,11 +1316,9 @@ pub const ServerConfig = struct {
}
if (global.hasException()) return error.JSError;

if (try arg.getTruthy(global, "unix")) |unix| {
const unix_str = unix.toSlice(
global,
bun.default_allocator,
);
if (try arg.getStringish(global, "unix")) |unix| {
defer unix.deref();
const unix_str = unix.toUTF8(bun.default_allocator);
defer unix_str.deinit();
if (unix_str.len > 0) {
if (has_hostname) {
Expand Down
2 changes: 1 addition & 1 deletion src/bun.js/bindings/ExposeNodeModuleGlobals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,4 @@ extern "C" void Bun__ExposeNodeModuleGlobals(Zig::GlobalObject* globalObject)
0 | JSC::PropertyAttribute::CustomValue
);
}
}
}
5 changes: 3 additions & 2 deletions src/bun.js/bindings/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,9 @@ JSC__JSValue JSC__JSValue__getIfPropertyExistsImpl(JSC__JSValue JSValue0,

JSC::VM& vm = globalObject->vm();
JSC::JSObject* object = value.getObject();
if (UNLIKELY(!object))
return JSValue::encode({});
if (UNLIKELY(!object)) {
return JSValue::encode(JSValue::decode(JSC::JSValue::ValueDeleted));
}

// Since Identifier might not ref' the string, we need to ensure it doesn't get deref'd until this function returns
const auto propertyString = String(StringImpl::createWithoutCopying({ arg1, arg2 }));
Expand Down
Loading

0 comments on commit 8ca0eb8

Please sign in to comment.