diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-03-14 19:50:52 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-03-15 10:48:15 -0700 |
| commit | 4aa5895d322c58cfa654e890beccc1009d49c6e5 (patch) | |
| tree | ddd3ff7b8cb424544beb4237df45aa0165b061c9 /lib/std/Build/Step.zig | |
| parent | 4f1382e58166c4324f842450fdad4d134d553085 (diff) | |
| download | zig-4aa5895d322c58cfa654e890beccc1009d49c6e5.tar.gz zig-4aa5895d322c58cfa654e890beccc1009d49c6e5.zip | |
std.Build: fix invalid assumption about fifos
Previously this code asserted that a fifo's readable length was greater
than or equal to the length of its readable slice, which was an invalid
assertion.
This code avoids making that assumption.
Diffstat (limited to 'lib/std/Build/Step.zig')
| -rw-r--r-- | lib/std/Build/Step.zig | 99 |
1 files changed, 50 insertions, 49 deletions
diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 123122a74b..88580a6cbc 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -321,56 +321,57 @@ pub fn evalZigProcess( const stdout = poller.fifo(.stdout); - poll: while (try poller.poll()) { - while (true) { - const buf = stdout.readableSlice(0); - assert(stdout.readableLength() == buf.len); - if (buf.len < @sizeOf(Header)) continue :poll; - const header = @ptrCast(*align(1) const Header, buf[0..@sizeOf(Header)]); - const header_and_msg_len = header.bytes_len + @sizeOf(Header); - if (buf.len < header_and_msg_len) continue :poll; - const body = buf[@sizeOf(Header)..][0..header.bytes_len]; - switch (header.tag) { - .zig_version => { - if (!std.mem.eql(u8, builtin.zig_version_string, body)) { - return s.fail( - "zig version mismatch build runner vs compiler: '{s}' vs '{s}'", - .{ builtin.zig_version_string, body }, - ); - } - }, - .error_bundle => { - const EbHdr = std.zig.Server.Message.ErrorBundle; - const eb_hdr = @ptrCast(*align(1) const EbHdr, body); - const extra_bytes = - body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len]; - const string_bytes = - body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len]; - // TODO: use @ptrCast when the compiler supports it - const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes); - const extra_array = try arena.alloc(u32, unaligned_extra.len); - // TODO: use @memcpy when it supports slices - for (extra_array, unaligned_extra) |*dst, src| dst.* = src; - s.result_error_bundle = .{ - .string_bytes = try arena.dupe(u8, string_bytes), - .extra = extra_array, - }; - }, - .progress => { - node_name.clearRetainingCapacity(); - try node_name.appendSlice(gpa, body); - sub_prog_node.setName(node_name.items); - }, - .emit_bin_path => { - const EbpHdr = std.zig.Server.Message.EmitBinPath; - const ebp_hdr = @ptrCast(*align(1) const EbpHdr, body); - s.result_cached = ebp_hdr.flags.cache_hit; - result = try arena.dupe(u8, body[@sizeOf(EbpHdr)..]); - }, - else => {}, // ignore other messages - } - stdout.discard(header_and_msg_len); + poll: while (true) { + while (stdout.readableLength() < @sizeOf(Header)) { + if (!(try poller.poll())) break :poll; + } + const header = stdout.reader().readStruct(Header) catch unreachable; + while (stdout.readableLength() < header.bytes_len) { + if (!(try poller.poll())) break :poll; } + const body = stdout.readableSliceOfLen(header.bytes_len); + + switch (header.tag) { + .zig_version => { + if (!std.mem.eql(u8, builtin.zig_version_string, body)) { + return s.fail( + "zig version mismatch build runner vs compiler: '{s}' vs '{s}'", + .{ builtin.zig_version_string, body }, + ); + } + }, + .error_bundle => { + const EbHdr = std.zig.Server.Message.ErrorBundle; + const eb_hdr = @ptrCast(*align(1) const EbHdr, body); + const extra_bytes = + body[@sizeOf(EbHdr)..][0 .. @sizeOf(u32) * eb_hdr.extra_len]; + const string_bytes = + body[@sizeOf(EbHdr) + extra_bytes.len ..][0..eb_hdr.string_bytes_len]; + // TODO: use @ptrCast when the compiler supports it + const unaligned_extra = std.mem.bytesAsSlice(u32, extra_bytes); + const extra_array = try arena.alloc(u32, unaligned_extra.len); + // TODO: use @memcpy when it supports slices + for (extra_array, unaligned_extra) |*dst, src| dst.* = src; + s.result_error_bundle = .{ + .string_bytes = try arena.dupe(u8, string_bytes), + .extra = extra_array, + }; + }, + .progress => { + node_name.clearRetainingCapacity(); + try node_name.appendSlice(gpa, body); + sub_prog_node.setName(node_name.items); + }, + .emit_bin_path => { + const EbpHdr = std.zig.Server.Message.EmitBinPath; + const ebp_hdr = @ptrCast(*align(1) const EbpHdr, body); + s.result_cached = ebp_hdr.flags.cache_hit; + result = try arena.dupe(u8, body[@sizeOf(EbpHdr)..]); + }, + else => {}, // ignore other messages + } + + stdout.discard(body.len); } const stderr = poller.fifo(.stderr); |
