Skip to content

Commit

Permalink
Merge branch 'main' into nektro-patch-25869
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner authored Mar 29, 2024
2 parents 2032936 + 093e9c2 commit a56ca42
Show file tree
Hide file tree
Showing 35 changed files with 186 additions and 74 deletions.
2 changes: 1 addition & 1 deletion scripts/build-libarchive.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Push-Location (Join-Path $BUN_DEPS_DIR 'libarchive')
try {
Set-Location (mkdir -Force build)

Run cmake @CMAKE_FLAGS -DBUILD_SHARED_LIBS=OFF -DENABLE_TEST=OFF -DENABLE_INSTALL=OFF -DENABLE_WERROR=0 ..
Run cmake @CMAKE_FLAGS -DBUILD_SHARED_LIBS=OFF -DENABLE_TEST=OFF -DENABLE_INSTALL=OFF -DENABLE_WERROR=0 -DENABLE_ICONV=0 -DENABLE_LibGCC=0 -DENABLE_LZMA=0 -DENABLE_LZ4=0 -DENABLE_LIBXML2=0 -DENABLE_LIBB2=0 -DENABLE_OPENSSL=0 -DENABLE_CAT=0 ..
Run cmake --build . --clean-first --config Release

Copy-Item libarchive\archive_static.lib $BUN_DEPS_OUT_DIR\archive.lib
Expand Down
18 changes: 6 additions & 12 deletions src/StandaloneModuleGraph.zig
Original file line number Diff line number Diff line change
Expand Up @@ -277,19 +277,16 @@ pub const StandaloneModuleGraph = struct {
}.toClean;

const cloned_executable_fd: bun.FileDescriptor = brk: {
var self_buf: [bun.MAX_PATH_BYTES + 1]u8 = undefined;
const self_exe = std.fs.selfExePath(&self_buf) catch |err| {
const self_exe = bun.selfExePath() catch |err| {
Output.prettyErrorln("<r><red>error<r><d>:<r> failed to get self executable path: {s}", .{@errorName(err)});
Global.exit(1);
};
self_buf[self_exe.len] = 0;
const self_exeZ = self_buf[0..self_exe.len :0];

if (comptime Environment.isWindows) {
// copy self and then open it for writing

var in_buf: bun.WPathBuffer = undefined;
strings.copyU8IntoU16(&in_buf, self_exeZ);
strings.copyU8IntoU16(&in_buf, self_exe);
in_buf[self_exe.len] = 0;
const in = in_buf[0..self_exe.len :0];
var out_buf: bun.WPathBuffer = undefined;
Expand All @@ -301,7 +298,6 @@ pub const StandaloneModuleGraph = struct {
Output.prettyErrorln("<r><red>error<r><d>:<r> failed to copy bun executable into temporary file: {s}", .{@errorName(err)});
Global.exit(1);
};

const file = bun.sys.openFileAtWindows(
bun.invalid_fd,
out,
Expand All @@ -322,7 +318,7 @@ pub const StandaloneModuleGraph = struct {
if (comptime Environment.isMac) {
// if we're on a mac, use clonefile() if we can
// failure is okay, clonefile is just a fast path.
if (Syscall.clonefile(self_exeZ, zname) == .result) {
if (Syscall.clonefile(self_exe, zname) == .result) {
switch (Syscall.open(zname, std.os.O.RDWR | std.os.O.CLOEXEC, 0)) {
.result => |res| break :brk res,
.err => {},
Expand Down Expand Up @@ -376,7 +372,7 @@ pub const StandaloneModuleGraph = struct {
};
const self_fd = brk2: {
for (0..3) |retry| {
switch (Syscall.open(self_exeZ, std.os.O.CLOEXEC | std.os.O.RDONLY, 0)) {
switch (Syscall.open(self_exe, std.os.O.CLOEXEC | std.os.O.RDONLY, 0)) {
.result => |res| break :brk2 res,
.err => |err| {
if (retry < 2) {
Expand Down Expand Up @@ -733,10 +729,8 @@ pub const StandaloneModuleGraph = struct {
.mac => {
// Use of MAX_PATH_BYTES here is valid as the resulting path is immediately
// opened with no modification.
var buf: [bun.MAX_PATH_BYTES]u8 = undefined;
const self_exe_path = try std.fs.selfExePath(&buf);
buf[self_exe_path.len] = 0;
const file = try std.fs.openFileAbsoluteZ(buf[0..self_exe_path.len :0].ptr, .{});
const self_exe_path = try bun.selfExePath();
const file = try std.fs.openFileAbsoluteZ(self_exe_path.ptr, .{});
return bun.toFD(file.handle);
},
.windows => {
Expand Down
13 changes: 10 additions & 3 deletions src/bun.js/api/bun/spawn/stdio.zig
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,10 @@ pub const Stdio = union(enum) {
}
}
} else if (value.asArrayBuffer(globalThis)) |array_buffer| {
if (array_buffer.slice().len == 0) {
globalThis.throwInvalidArguments("ArrayBuffer cannot be empty", .{});
return false;
// Change in Bun v1.0.34: don't throw for empty ArrayBuffer
if (array_buffer.byteSlice().len == 0) {
out_stdio.* = .{ .ignore = {} };
return true;
}

out_stdio.* = .{
Expand Down Expand Up @@ -475,6 +476,12 @@ pub const Stdio = union(enum) {
return false;
}

// Instead of writing an empty blob, lets just make it /dev/null
if (blob.fastSize() == 0) {
stdio.* = .{ .ignore = {} };
return true;
}

stdio.* = .{ .blob = blob };
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/bun.js/bindings/webcore/JSDOMURL.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ using JSDOMURLDOMConstructor = JSDOMConstructor<JSDOMURL>;
static const HashTableValue JSDOMURLConstructorTableValues[] = {
{ "createObjectURL"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsDOMURLConstructorFunction_createObjectURL, 1 } },
{ "revokeObjectURL"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsDOMURLConstructorFunction_revokeObjectURL, 1 } },
{ "canParse"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsDOMURLConstructorFunction_canParse, 2 } },
{ "canParse"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsDOMURLConstructorFunction_canParse, 1 } },
};

static inline JSC::EncodedJSValue constructJSDOMURL1(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
Expand Down
3 changes: 2 additions & 1 deletion src/bun.js/javascript.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1925,7 +1925,8 @@ pub const VirtualMachine = struct {
}

const old_log = jsc_vm.log;
var log = logger.Log.init(jsc_vm.allocator);
// the logger can end up being called on another thread, it must not use threadlocal Heap Allocator
var log = logger.Log.init(bun.default_allocator);
defer log.deinit();
jsc_vm.log = &log;
jsc_vm.bundler.resolver.log = &log;
Expand Down
5 changes: 2 additions & 3 deletions src/bun.js/node/types.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4852,8 +4852,7 @@ pub const Process = struct {
}

pub fn getExecPath(globalObject: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
var buf: bun.PathBuffer = undefined;
const out = std.fs.selfExePath(&buf) catch {
const out = bun.selfExePath() catch {
// if for any reason we are unable to get the executable path, we just return argv[0]
return getArgv0(globalObject);
};
Expand Down Expand Up @@ -4935,7 +4934,7 @@ pub const Process = struct {
bun.String.static("bun"),
);
} else {
const exe_path = std.fs.selfExePathAlloc(allocator) catch null;
const exe_path = bun.selfExePath() catch null;
args_list.appendAssumeCapacity(
if (exe_path) |str| bun.String.fromUTF8(str) else bun.String.static("bun"),
);
Expand Down
6 changes: 5 additions & 1 deletion src/bun.js/webcore/response.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,11 @@ pub const Fetch = struct {
error.STORE_LOOKUP => bun.String.static("Issuer certificate lookup error"),
error.NAME_CONSTRAINTS_WITHOUT_SANS => bun.String.static("Issuer has name constraints but leaf has no SANs"),
error.UNKKNOW_CERTIFICATE_VERIFICATION_ERROR => bun.String.static("unknown certificate verification error"),
else => bun.String.static("fetch() failed. For more information, pass `verbose: true` in the second argument to fetch()"),

else => |e| bun.String.createFormat("{s} fetching \"{}\". For more information, pass `verbose: true` in the second argument to fetch()", .{
@errorName(e),
path,
}) catch bun.outOfMemory(),
},
.path = path,
};
Expand Down
33 changes: 32 additions & 1 deletion src/bun.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1562,7 +1562,7 @@ pub fn reloadProcess(
}

// we must clone selfExePath incase the argv[0] was not an absolute path (what appears in the terminal)
const exec_path = (allocator.dupeZ(u8, std.fs.selfExePathAlloc(allocator) catch unreachable) catch unreachable).ptr;
const exec_path = (bun.selfExePath() catch unreachable).ptr;

// we clone argv so that the memory address isn't the same as the libc one
const newargv = @as([*:null]?[*:0]const u8, @ptrCast(dupe_argv.ptr));
Expand Down Expand Up @@ -2816,6 +2816,37 @@ pub fn linuxKernelVersion() Semver.Version {
return @import("./analytics.zig").GenerateHeader.GeneratePlatform.kernelVersion();
}

pub fn selfExePath() ![:0]u8 {
const memo = struct {
var set = false;
// TODO open zig issue to make 'std.fs.selfExePath' return [:0]u8 directly
// note: this doesn't use MAX_PATH_BYTES because on windows that's 32767*3+1 yet normal paths are 255.
// should this fail it will still do so gracefully. 4096 is MAX_PATH_BYTES on posix.
var value: [
4096 + 1 // + 1 for the null terminator
]u8 = undefined;
var len: usize = 0;
var lock = Lock.init();

pub fn load() ![:0]u8 {
const init = try std.fs.selfExePath(&value);
@This().len = init.len;
value[@This().len] = 0;
set = true;
return value[0..@This().len :0];
}
};

// try without a lock
if (memo.set) return memo.value[0..memo.len :0];

// make it thread-safe
memo.lock.lock();
defer memo.lock.unlock();
// two calls could happen concurrently, so we must check again
if (memo.set) return memo.value[0..memo.len :0];
return memo.load();
}
pub const exe_suffix = if (Environment.isWindows) ".exe" else "";

pub const spawnSync = @This().spawn.sync.spawn;
2 changes: 1 addition & 1 deletion src/cli/bunx_command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ pub const BunxCommand = struct {
}

var args = std.BoundedArray([]const u8, 7).fromSlice(&.{
try std.fs.selfExePathAlloc(ctx.allocator),
try bun.selfExePath(),
"add",
install_param,
"--no-summary",
Expand Down
2 changes: 1 addition & 1 deletion src/cli/create_command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1400,7 +1400,7 @@ pub const CreateCommand = struct {
if (!create_options.skip_install) {
npm_client_ = NPMClient{
.tag = .bun,
.bin = try std.fs.selfExePathAlloc(ctx.allocator),
.bin = try bun.selfExePath(),
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/cli/init_command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ pub const InitCommand = struct {
if (exists("package.json")) {
var process = std.ChildProcess.init(
&.{
try std.fs.selfExePathAlloc(alloc),
try bun.selfExePath(),
"install",
},
alloc,
Expand Down
14 changes: 7 additions & 7 deletions src/cli/install_completions_command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ pub const InstallCompletionsCommand = struct {

const bunx_name = if (Environment.isDebug) "bunx-debug" else "bunx";

fn installBunxSymlinkPosix(allocator: std.mem.Allocator, cwd: []const u8) !void {
fn installBunxSymlinkPosix(cwd: []const u8) !void {
var buf: [bun.MAX_PATH_BYTES]u8 = undefined;

// don't install it if it's already there
if (bun.which(&buf, bun.getenvZ("PATH") orelse cwd, cwd, bunx_name) != null)
return;

// first try installing the symlink into the same directory as the bun executable
const exe = try std.fs.selfExePathAlloc(allocator);
const exe = try bun.selfExePath();
var target_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
var target = std.fmt.bufPrint(&target_buf, "{s}/" ++ bunx_name, .{std.fs.path.dirname(exe).?}) catch unreachable;
std.os.symlink(exe, target) catch {
Expand Down Expand Up @@ -89,7 +89,7 @@ pub const InstallCompletionsCommand = struct {
};
}

fn installBunxSymlinkWindows(_: std.mem.Allocator, _: []const u8) !void {
fn installBunxSymlinkWindows(_: []const u8) !void {
// Because symlinks are not always allowed on windows,
// `bunx.exe` on windows is a hardlink to `bun.exe`
// for this to work, we need to delete and recreate the hardlink every time
Expand Down Expand Up @@ -130,11 +130,11 @@ pub const InstallCompletionsCommand = struct {
}
}

fn installBunxSymlink(allocator: std.mem.Allocator, cwd: []const u8) !void {
fn installBunxSymlink(cwd: []const u8) !void {
if (Environment.isWindows) {
try installBunxSymlinkWindows(allocator, cwd);
try installBunxSymlinkWindows(cwd);
} else {
try installBunxSymlinkPosix(allocator, cwd);
try installBunxSymlinkPosix(cwd);
}
}

Expand Down Expand Up @@ -190,7 +190,7 @@ pub const InstallCompletionsCommand = struct {
Global.exit(fail_exit_code);
};

installBunxSymlink(allocator, cwd) catch {};
installBunxSymlink(cwd) catch {};

if (Environment.isWindows) {
installUninstallerWindows() catch {};
Expand Down
9 changes: 3 additions & 6 deletions src/cli/run_command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -706,8 +706,6 @@ pub const RunCommand = struct {
return try allocator.dupeZ(u8, target_path_buffer[0 .. converted.len + file_name.len :0]);
}

var self_exe_bin_path_buf: [bun.MAX_PATH_BYTES + 1]u8 = undefined;

pub fn createFakeTemporaryNodeExecutable(PATH: *std.ArrayList(u8), optional_bun_path: *string) !void {
// If we are already running as "node", the path should exist
if (CLI.pretend_to_be_node) return;
Expand All @@ -722,10 +720,9 @@ pub const RunCommand = struct {
argv0 = bun.argv()[0];
} else if (optional_bun_path.len == 0) {
// otherwise, ask the OS for the absolute path
var self = try std.fs.selfExePath(&self_exe_bin_path_buf);
const self = try bun.selfExePath();
if (self.len > 0) {
self.ptr[self.len] = 0;
argv0 = @as([*:0]const u8, @ptrCast(self.ptr));
argv0 = self.ptr;
optional_bun_path.* = self;
}
}
Expand Down Expand Up @@ -900,7 +897,7 @@ pub const RunCommand = struct {

if (this_bundler.env.get("npm_execpath") == null) {
// we don't care if this fails
if (std.fs.selfExePathAlloc(ctx.allocator)) |self_exe_path| {
if (bun.selfExePath()) |self_exe_path| {
this_bundler.env.map.putDefault("npm_execpath", self_exe_path) catch unreachable;
} else |_| {}
}
Expand Down
3 changes: 2 additions & 1 deletion src/cli/upgrade_command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,8 @@ pub const UpgradeCommand = struct {
}
}

const destination_executable = std.fs.selfExePath(&current_executable_buf) catch return error.UpgradeFailedMissingExecutable;
const destination_executable = bun.selfExePath() catch return error.UpgradeFailedMissingExecutable;
@memcpy((&current_executable_buf).ptr, destination_executable);
current_executable_buf[destination_executable.len] = 0;

const target_filename_ = std.fs.path.basename(destination_executable);
Expand Down
12 changes: 12 additions & 0 deletions src/js/node/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -3388,9 +3388,21 @@ var require_readable = __commonJS({
};

Readable.fromWeb = function (readableStream, options) {
// We cache .stream() calls for file descriptors
// This won't create a new ReadableStream each time.
let bunStdinStream = Bun.stdin.stream();
if (readableStream === bunStdinStream) {
return bunStdinStream;
}

return webStreamsAdapters.newStreamReadableFromReadableStream(readableStream, options);
};
Readable.toWeb = function (streamReadable, options) {
// Workaround for https://github.com/oven-sh/bun/issues/9041
if (streamReadable === process.stdin) {
return Bun.stdin.stream();
}

return webStreamsAdapters.newReadableStreamFromStreamReadable(streamReadable, options);
};
Readable.wrap = function (src, options) {
Expand Down
2 changes: 0 additions & 2 deletions src/options.zig
Original file line number Diff line number Diff line change
Expand Up @@ -580,13 +580,11 @@ pub const Target = enum {
});
array.set(Target.bun, &[_]string{
"bun",
"worker",
"node",
});
array.set(Target.bun_macro, &[_]string{
"macro",
"bun",
"worker",
"node",
});

Expand Down
6 changes: 6 additions & 0 deletions src/shell/interpreter.zig
Original file line number Diff line number Diff line change
Expand Up @@ -511,11 +511,17 @@ pub const EnvMap = struct {
const MapType = std.ArrayHashMap(EnvStr, EnvStr, struct {
pub fn hash(self: @This(), s: EnvStr) u32 {
_ = self;
if (bun.Environment.isWindows) {
return bun.CaseInsensitiveASCIIStringContext.hash(undefined, s.slice());
}
return std.array_hash_map.hashString(s.slice());
}
pub fn eql(self: @This(), a: EnvStr, b: EnvStr, b_index: usize) bool {
_ = self;
_ = b_index;
if (bun.Environment.isWindows) {
return bun.CaseInsensitiveASCIIStringContext.eql(undefined, a.slice(), b.slice(), undefined);
}
return std.array_hash_map.eqlString(a.slice(), b.slice());
}
}, true);
Expand Down
8 changes: 8 additions & 0 deletions src/string.zig
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,14 @@ pub const String = extern struct {
return BunString__fromUTF16(bytes.ptr, bytes.len);
}

pub fn createFormat(comptime fmt: []const u8, args: anytype) !String {
var sba = std.heap.stackFallback(16384, bun.default_allocator);
const alloc = sba.get();
const buf = try std.fmt.allocPrint(alloc, fmt, args);
defer alloc.free(buf);
return createUTF8(buf);
}

pub fn createFromOSPath(os_path: bun.OSPathSlice) String {
return switch (@TypeOf(os_path)) {
[]const u8 => createUTF8(os_path),
Expand Down
4 changes: 0 additions & 4 deletions test/cli/install/bad-workspace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ beforeEach(() => {
cwd = mkdtempSync(join(realpathSync(tmpdir()), "bad-workspace.test"));
});

afterEach(() => {
rmSync(cwd, { recursive: true, force: true });
});

test("bad workspace path", () => {
writeFileSync(
`${cwd}/package.json`,
Expand Down
Loading

0 comments on commit a56ca42

Please sign in to comment.