diff options
author | 2022-11-14 17:52:52 -0800 | |
---|---|---|
committer | 2022-11-14 17:53:15 -0800 | |
commit | 436b8e14611e346fdb2c581a7c137f1dde10f1b0 (patch) | |
tree | 2c06462ecaf469894aad5c34b1440cf07707e9cb | |
parent | 272e71fec2117bc759b2a41e0eaf985f9b064e51 (diff) | |
download | bun-436b8e14611e346fdb2c581a7c137f1dde10f1b0.tar.gz bun-436b8e14611e346fdb2c581a7c137f1dde10f1b0.tar.zst bun-436b8e14611e346fdb2c581a7c137f1dde10f1b0.zip |
Fix crashiness with `process.env`
This also makes it a lot slower
-rw-r--r-- | src/bun.js/api/bun.zig | 81 | ||||
-rw-r--r-- | test/bun.js/process.test.js | 12 |
2 files changed, 66 insertions, 27 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig index 727712897..b6abde2b0 100644 --- a/src/bun.js/api/bun.zig +++ b/src/bun.js/api/bun.zig @@ -3310,17 +3310,17 @@ pub const EnvironmentVariables = struct { propertyName: js.JSStringRef, _: js.ExceptionRef, ) callconv(.C) js.JSValueRef { - const len = js.JSStringGetLength(propertyName); - var ptr = js.JSStringGetCharacters8Ptr(propertyName); - var name = ptr[0..len]; + var name_slice = propertyName.toZigString().toSlice(ctx.allocator()); + defer name_slice.deinit(); + var name = name_slice.slice(); if (VirtualMachine.vm.bundler.env.map.get(name)) |value| { - return ZigString.toRef(value, ctx.ptr()); + return ZigString.init(value).withEncoding().toValueGC(ctx).asObjectRef(); } if (Output.enable_ansi_colors) { // https://github.com/chalk/supports-color/blob/main/index.js if (strings.eqlComptime(name, "FORCE_COLOR")) { - return ZigString.toRef(BooleanString.@"true", ctx.ptr()); + return ZigString.static("\"true\"").toValue(ctx).asObjectRef(); } } @@ -3364,46 +3364,71 @@ pub const EnvironmentVariables = struct { } pub fn deleteProperty( - _: js.JSContextRef, + globalThis: js.JSContextRef, _: js.JSObjectRef, propertyName: js.JSStringRef, _: js.ExceptionRef, ) callconv(.C) bool { - const len = js.JSStringGetLength(propertyName); - var ptr = js.JSStringGetCharacters8Ptr(propertyName); - var name = ptr[0..len]; - _ = VirtualMachine.vm.bundler.env.map.map.swapRemove(name); - return true; + var jsc_vm = globalThis.bunVM(); + const allocator = jsc_vm.allocator; + + const zig_str = propertyName.toZigString(); + + var str = zig_str.toSlice(allocator); + defer str.deinit(); + const name = str.slice(); + + if (jsc_vm.bundler.env.map.map.fetchSwapRemove(name)) |entry| { + allocator.free(bun.constStrToU8(entry.value)); + allocator.free(bun.constStrToU8(entry.key)); + return true; + } + + return false; } pub fn setProperty( - ctx: js.JSContextRef, + globalThis: js.JSContextRef, _: js.JSObjectRef, propertyName: js.JSStringRef, value: js.JSValueRef, - exception: js.ExceptionRef, + _: js.ExceptionRef, ) callconv(.C) bool { - const len = js.JSStringGetLength(propertyName); - var ptr = js.JSStringGetCharacters8Ptr(propertyName); - var name = ptr[0..len]; - var val = ZigString.init(""); - JSValue.fromRef(value).toZigString(&val, ctx.ptr()); - if (exception.* != null) return false; - var result = std.fmt.allocPrint(VirtualMachine.vm.allocator, "{}", .{val}) catch unreachable; - VirtualMachine.vm.bundler.env.map.put(name, result) catch unreachable; + var jsc_vm = globalThis.bunVM(); + const allocator = jsc_vm.allocator; + + const zig_str = propertyName.toZigString(); + + var str = zig_str.toSlice(allocator); + const name = str.slice(); + var entry = jsc_vm.bundler.env.map.map.getOrPut(name) catch return false; + if (!entry.found_existing) { + const value_str = value.?.value().toSlice(globalThis, allocator).cloneIfNeeded(allocator) catch return false; + entry.key_ptr.* = (str.cloneIfNeeded(allocator) catch return false).slice(); + + entry.value_ptr.* = value_str.slice(); + } else { + allocator.free(bun.constStrToU8(entry.value_ptr.*)); + const cloned_value = value.?.value().toSlice(globalThis, allocator).cloneIfNeeded(allocator) catch return false; + entry.value_ptr.* = cloned_value.slice(); + } return true; } pub fn hasProperty( - _: js.JSContextRef, + globalThis: js.JSContextRef, _: js.JSObjectRef, propertyName: js.JSStringRef, ) callconv(.C) bool { - const len = js.JSStringGetLength(propertyName); - const ptr = js.JSStringGetCharacters8Ptr(propertyName); - const name = ptr[0..len]; - return VirtualMachine.vm.bundler.env.map.get(name) != null or (Output.enable_ansi_colors and strings.eqlComptime(name, "FORCE_COLOR")); + var jsc_vm = globalThis.bunVM(); + const allocator = jsc_vm.allocator; + + const zig_str = propertyName.toZigString(); + var str = zig_str.toSlice(allocator); + defer str.deinit(); + const name = str.slice(); + return jsc_vm.bundler.env.map.get(name) != null or (Output.enable_ansi_colors and strings.eqlComptime(name, "FORCE_COLOR")); } pub fn convertToType(ctx: js.JSContextRef, obj: js.JSObjectRef, kind: js.JSType, exception: js.ExceptionRef) callconv(.C) js.JSValueRef { @@ -3423,7 +3448,9 @@ pub const EnvironmentVariables = struct { while (iter.next()) |item| { const str = item.key_ptr.*; - js.JSPropertyNameAccumulatorAddName(props, js.JSStringCreateStatic(str.ptr, str.len)); + var init_str = ZigString.init(str); + init_str.markUTF8(); + js.JSPropertyNameAccumulatorAddName(props, JSC.C.OpaqueJSString.fromZigString(init_str, VirtualMachine.vm.allocator)); } } }; diff --git a/test/bun.js/process.test.js b/test/bun.js/process.test.js index 296e786cf..e221375d1 100644 --- a/test/bun.js/process.test.js +++ b/test/bun.js/process.test.js @@ -75,3 +75,15 @@ it("process.release", () => { }-${{ arm64: "aarch64", x64: "x64" }[process.arch] || process.arch}.zip`, ); }); + +it("process.env", () => { + process.env["LOL SMILE UTF16 😂"] = "😂"; + expect(process.env["LOL SMILE UTF16 😂"]).toBe("😂"); + delete process.env["LOL SMILE UTF16 😂"]; + expect(process.env["LOL SMILE UTF16 😂"]).toBe(undefined); + + process.env["LOL SMILE latin1 <abc>"] = "<abc>"; + expect(process.env["LOL SMILE latin1 <abc>"]).toBe("<abc>"); + delete process.env["LOL SMILE latin1 <abc>"]; + expect(process.env["LOL SMILE latin1 <abc>"]).toBe(undefined); +}); |