diff --git a/src/bun.js/bindings/JSEnvironmentVariableMap.cpp b/src/bun.js/bindings/JSEnvironmentVariableMap.cpp index dd64f6130d..de0523a0e4 100644 --- a/src/bun.js/bindings/JSEnvironmentVariableMap.cpp +++ b/src/bun.js/bindings/JSEnvironmentVariableMap.cpp @@ -24,45 +24,6 @@ namespace Bun { using namespace WebCore; -JSC_DEFINE_CUSTOM_GETTER(jsGetterEnvironmentVariable, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName propertyName)) -{ - VM& vm = globalObject->vm(); - auto scope = DECLARE_THROW_SCOPE(vm); - - auto* thisObject = jsDynamicCast(JSValue::decode(thisValue)); - if (UNLIKELY(!thisObject)) - return JSValue::encode(jsUndefined()); - - ZigString name = toZigString(propertyName.publicName()); - ZigString value = { nullptr, 0 }; - - if (UNLIKELY(name.len == 0)) - return JSValue::encode(jsUndefined()); - - if (!Bun__getEnvValue(globalObject, &name, &value)) { - return JSValue::encode(jsUndefined()); - } - - JSValue result = jsString(vm, Zig::toStringCopy(value)); - thisObject->putDirect(vm, propertyName, result, 0); - return JSValue::encode(result); -} - -JSC_DEFINE_CUSTOM_SETTER(jsSetterEnvironmentVariable, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::EncodedJSValue value, PropertyName propertyName)) -{ - VM& vm = globalObject->vm(); - JSC::JSObject* object = JSValue::decode(thisValue).getObject(); - if (!object) - return false; - - auto string = JSValue::decode(value).toString(globalObject); - if (UNLIKELY(!string)) - return false; - - object->putDirect(vm, propertyName, string, 0); - return true; -} - JSC_DEFINE_CUSTOM_GETTER(jsTimeZoneEnvironmentVariableGetter, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName propertyName)) { VM& vm = globalObject->vm(); @@ -264,7 +225,6 @@ JSC_DEFINE_HOST_FUNCTION(jsEditWindowsEnvVar, (JSGlobalObject * global, JSC::Cal WTF::String string1 = callFrame->uncheckedArgument(0).toWTFString(global); RETURN_IF_EXCEPTION(scope, {}); JSValue arg2 = callFrame->uncheckedArgument(1); - ASSERT(arg2.isNull() || arg2.isString()); if (arg2.isCell()) { WTF::String string2 = arg2.toWTFString(global); RETURN_IF_EXCEPTION(scope, {}); @@ -340,11 +300,14 @@ JSValue createEnvironmentVariablesMap(Zig::GlobalObject* globalObject) void* list; size_t count = Bun__getEnvCount(globalObject, &list); +#if OS(WINDOWS) + auto* object = constructEmptyObject(globalObject, globalObject->objectPrototype()); +#else auto* object = JSEnvironmentVariableMap::create(vm, globalObject, JSEnvironmentVariableMap::createStructure(vm, globalObject, globalObject->objectPrototype())); +#endif #if OS(WINDOWS) - JSArray* keyArray - = constructEmptyArray(globalObject, nullptr, count); + JSArray* keyArray = constructEmptyArray(globalObject, nullptr, count); #endif static NeverDestroyed TZ = MAKE_STATIC_STRING_IMPL("TZ"); @@ -394,8 +357,6 @@ JSValue createEnvironmentVariablesMap(Zig::GlobalObject* globalObject) continue; } } - - object->putDirectCustomAccessor(vm, identifier, JSC::CustomGetterSetter::create(vm, jsGetterEnvironmentVariable, jsSetterEnvironmentVariable), JSC::PropertyAttribute::CustomAccessor | 0); } unsigned int TZAttrs = JSC::PropertyAttribute::CustomAccessor | 0; diff --git a/src/bun.js/node/node_process.zig b/src/bun.js/node/node_process.zig index 1be6cd62ec..2cfaeda88e 100644 --- a/src/bun.js/node/node_process.zig +++ b/src/bun.js/node/node_process.zig @@ -270,6 +270,7 @@ pub fn exit(globalObject: *JSC.JSGlobalObject, code: u8) callconv(.c) void { pub fn Bun__Process__editWindowsEnvVar(k: bun.String, v: bun.String) callconv(.C) void { comptime bun.assert(bun.Environment.isWindows); if (k.tag == .Empty) return; + if (v.tag == .Empty) return; const wtf1 = k.value.WTFStringImpl; var fixed_stack_allocator = std.heap.stackFallback(1025, bun.default_allocator); const allocator = fixed_stack_allocator.get(); diff --git a/src/js/builtins/ProcessObjectInternals.ts b/src/js/builtins/ProcessObjectInternals.ts index cbb2de0c74..8e6d5114eb 100644 --- a/src/js/builtins/ProcessObjectInternals.ts +++ b/src/js/builtins/ProcessObjectInternals.ts @@ -373,10 +373,12 @@ export function windowsEnv( return new Proxy(internalEnv, { get(_, p) { - return typeof p === "string" ? internalEnv[p.toUpperCase()] : undefined; + return typeof p === "string" ? (internalEnv[p.toUpperCase()] ?? internalEnv[p]) : undefined; }, set(_, p, value) { const k = String(p).toUpperCase(); + if (typeof p === "symbol") throw new TypeError("Cannot convert a symbol to a string"); + if (typeof value === "symbol") throw new TypeError("Cannot convert a symbol to a string"); $assert(typeof p === "string"); // proxy is only string and symbol. the symbol would have thrown by now value = String(value); // If toString() throws, we want to avoid it existing in the envMapList if (!(k in internalEnv) && !envMapList.includes(p)) { @@ -392,6 +394,7 @@ export function windowsEnv( return typeof p !== "symbol" ? String(p).toUpperCase() in internalEnv : false; }, deleteProperty(_, p) { + if (typeof p === "symbol") return true; const k = String(p).toUpperCase(); const i = envMapList.findIndex(x => x.toUpperCase() === k); if (i !== -1) { @@ -401,6 +404,11 @@ export function windowsEnv( return typeof p !== "symbol" ? delete internalEnv[k] : false; }, defineProperty(_, p, attributes) { + if (attributes.get) throw $ERR_INVALID_OBJECT_DEFINE_PROPERTY(`'process.env' does not accept an accessor(getter/setter) descriptor`); + if (attributes.set) throw $ERR_INVALID_OBJECT_DEFINE_PROPERTY(`'process.env' does not accept an accessor(getter/setter) descriptor`); + if (!attributes.writable) throw $ERR_INVALID_OBJECT_DEFINE_PROPERTY(`'process.env' only accepts a configurable, writable, and enumerable data descriptor`); + if (!attributes.enumerable) throw $ERR_INVALID_OBJECT_DEFINE_PROPERTY(`'process.env' only accepts a configurable, writable, and enumerable data descriptor`); + if (!attributes.configurable) throw $ERR_INVALID_OBJECT_DEFINE_PROPERTY(`'process.env' only accepts a configurable, writable, and enumerable data descriptor`); const k = String(p).toUpperCase(); $assert(typeof p === "string"); // proxy is only string and symbol. the symbol would have thrown by now if (!(k in internalEnv) && !envMapList.includes(p)) { diff --git a/src/sys.zig b/src/sys.zig index 2ae5ba8702..f7b9b3e01b 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -1397,7 +1397,7 @@ pub fn openFileAtWindowsNtPath( bun.Output.debugWarn("NtCreateFile({}, {}) = {s} (file) = {d}\nYou are calling this function without normalizing the path correctly!!!", .{ dir, bun.fmt.utf16(path), @tagName(rc), @intFromPtr(result) }); } else { if (rc == .SUCCESS) { - log("NtCreateFile({}, {}) = {s} (file) = {}", .{ dir, bun.fmt.utf16(path), @tagName(rc), bun.toFD(result) }); + log("NtCreateFile({}, {}) = {s} (file) = {}", .{ dir, bun.fmt.utf16(path), @tagName(rc), bun.FD.fromNative(result) }); } else { log("NtCreateFile({}, {}) = {s} (file) = {}", .{ dir, bun.fmt.utf16(path), @tagName(rc), rc }); } diff --git a/test/js/node/test/parallel/test-process-env.js b/test/js/node/test/parallel/test-process-env.js index f20be5a194..2e457b9950 100644 --- a/test/js/node/test/parallel/test-process-env.js +++ b/test/js/node/test/parallel/test-process-env.js @@ -106,7 +106,8 @@ if (common.isWindows) { } // https://github.com/nodejs/node/issues/45380 -{ +// BUN: TODO: on windows +if (common.isWindows) { const env = structuredClone(process.env); // deepEqual(), not deepStrictEqual(), because of different prototypes. // eslint-disable-next-line no-restricted-properties