Compare commits

...

6 Commits

Author SHA1 Message Date
Jarred Sumner
72d4e5b227 Update PipeReader.zig 2025-07-20 05:42:28 -07:00
autofix-ci[bot]
4cf8cee1b4 [autofix.ci] apply automated fixes 2025-07-20 12:42:13 +00:00
Claude Bot
5aa9369e34 fix: correct slice length calculations in Windows PipeReader causing garbled stdout/stderr
Fixed three slice calculation issues in WindowsBufferedReader:
1. Line 954: Fixed slice range to use proper end bound
2. Line 1034: Fixed slice range to use proper end bound
3. Line 1164: Fixed slice passed to _onReadChunk to use actual amount read

These fixes prevent garbled output like:
Expected: "isMainThread true\nisMainThread false\n"
Received: "isMainThread true\n������������������isMainThread false\n�������������������"

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-20 12:38:42 +00:00
autofix-ci[bot]
1259cf988c [autofix.ci] apply automated fixes 2025-07-20 12:02:38 +00:00
Jarred Sumner
621151f7d7 Fix windows CI issue 2025-07-20 04:59:32 -07:00
Jarred Sumner
eeb91058c0 Update subprocess.zig 2025-07-20 04:34:21 -07:00
3 changed files with 47 additions and 25 deletions

View File

@@ -245,7 +245,6 @@ linker = "hoisted"
## CI/CD
Use the official [`oven-sh/setup-bun`](https://github.com/oven-sh/setup-bun) action to install `bun` in a GitHub Actions pipeline:
```yaml#.github/workflows/release.yml
@@ -292,6 +291,4 @@ jobs:
run: bun run build
```
{% bunCLIUsage command="install" /%}

View File

@@ -1579,12 +1579,12 @@ pub fn onProcessExit(this: *Subprocess, process: *Process, status: bun.spawn.Sta
pipe.onAttachedProcessExit(&status);
}
var did_update_has_pending_activity = false;
defer if (!did_update_has_pending_activity) this.updateHasPendingActivity();
const loop = jsc_vm.eventLoop();
if (!is_sync) {
var did_update_has_pending_activity = false;
defer if (!did_update_has_pending_activity) this.updateHasPendingActivity();
const loop = jsc_vm.eventLoop();
if (this_jsvalue != .zero) {
if (consumeExitedPromise(this_jsvalue, globalThis)) |promise| {
loop.enter();

View File

@@ -856,9 +856,7 @@ pub const WindowsBufferedReader = struct {
pub fn getReadBufferWithStableMemoryAddress(this: *WindowsBufferedReader, suggested_size: usize) []u8 {
this.flags.has_inflight_read = true;
this._buffer.ensureUnusedCapacity(suggested_size) catch bun.outOfMemory();
const res = this._buffer.allocatedSlice()[this._buffer.items.len..];
return res;
return bun.default_allocator.alloc(u8, suggested_size) catch bun.outOfMemory();
}
pub fn startWithCurrentPipe(this: *WindowsBufferedReader) bun.JSC.Maybe(void) {
@@ -921,7 +919,8 @@ pub const WindowsBufferedReader = struct {
fn onStreamRead(handle: *uv.uv_handle_t, nread: uv.ReturnCodeI64, buf: *const uv.uv_buf_t) callconv(.C) void {
const stream = bun.cast(*uv.uv_stream_t, handle);
var this = bun.cast(*WindowsBufferedReader, stream.data);
var to_free = buf.base[0..buf.len];
defer bun.default_allocator.free(to_free);
const nread_int = nread.int();
bun.sys.syslog("onStreamRead(0x{d}) = {d}", .{ @intFromPtr(this), nread_int });
@@ -946,8 +945,13 @@ pub const WindowsBufferedReader = struct {
}
// we got some data we can slice the buffer!
const len: usize = @intCast(nread_int);
var slice = buf.slice();
this.onRead(.{ .result = len }, slice[0..len], .progress);
// Append the data, ensure we free the uv_buf_t before calling into onRead.
this.buffer().appendSlice(to_free[0..len]) catch bun.outOfMemory();
bun.default_allocator.free(to_free);
to_free = &.{};
this.onRead(.{ .result = len }, this.buffer().items[this.buffer().items.len - len .. this.buffer().items.len], .progress);
},
}
}
@@ -956,11 +960,25 @@ pub const WindowsBufferedReader = struct {
const result = fs.result;
const nread_int = result.int();
bun.sys.syslog("onFileRead({}) = {d}", .{ bun.FD.fromUV(fs.file.fd), nread_int });
var buffer_to_free: []u8 = &.{};
defer bun.default_allocator.free(buffer_to_free);
var this: *WindowsBufferedReader = bun.cast(*WindowsBufferedReader, fs.data);
if (this.source) |*source| {
if (source.* == .file) {
buffer_to_free = source.file.iov.slice();
source.file.iov = .{
.base = undefined,
.len = 0,
};
}
}
if (nread_int == uv.UV_ECANCELED) {
fs.deinit();
return;
}
var this: *WindowsBufferedReader = bun.cast(*WindowsBufferedReader, fs.data);
fs.deinit();
if (this.flags.is_done) return;
@@ -988,6 +1006,12 @@ pub const WindowsBufferedReader = struct {
const buf = this.getReadBufferWithStableMemoryAddress(64 * 1024);
file.iov = uv.uv_buf_t.init(buf);
if (uv.uv_fs_read(uv.Loop.get(), &file.fs, file.file, @ptrCast(&file.iov), 1, if (this.flags.use_pread) @intCast(this._offset) else -1, onFileRead).toError(.write)) |err| {
bun.default_allocator.free(buf);
file.iov = .{
.base = undefined,
.len = 0,
};
this.flags.is_paused = true;
// we should inform the error if we are unable to keep reading
this.onRead(.{ .err = err }, "", .progress);
@@ -1000,14 +1024,17 @@ pub const WindowsBufferedReader = struct {
const len: usize = @intCast(nread_int);
this._offset += len;
// we got some data lets get the current iov
if (this.source) |source| {
if (source == .file) {
var buf = source.file.iov.slice();
return this.onRead(.{ .result = len }, buf[0..len], .progress);
if (this.source) |*source| {
if (source.* == .file) {
// Append the data, ensure we free the uv_buf_t before calling into onRead.
this.buffer().appendSlice(buffer_to_free[0..len]) catch bun.outOfMemory();
bun.default_allocator.free(buffer_to_free);
buffer_to_free = &.{};
return this.onRead(.{ .result = len }, this.buffer().items[this.buffer().items.len - len .. this.buffer().items.len], .progress);
}
}
// ops we should not hit this lets fail with EPIPE
bun.assert(false);
return this.onRead(.{ .err = bun.sys.Error.fromCode(bun.sys.E.PIPE, .read) }, "", .progress);
},
}
@@ -1128,14 +1155,12 @@ pub const WindowsBufferedReader = struct {
},
else => {
var buf = this.buffer();
if (comptime bun.Environment.allow_assert) {
if (comptime bun.Environment.is_canary) {
if (slice.len > 0 and !bun.isSliceInBuffer(slice, buf.allocatedSlice())) {
@panic("uv_read_cb: buf is not in buffer! This is a bug in bun. Please report it.");
}
}
// move cursor foward
buf.items.len += amount.result;
_ = this._onReadChunk(slice, hasMore);
_ = this._onReadChunk(slice[0..amount.result], hasMore);
},
}
}