authorgravatar for lukasl@noreply.codeberg.orgLukáš Lalinský <lukasl@noreply.codeberg.org> 2026-08-09 12:01:21+02:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-09 12:01:21+02:00
log49e20bd9dd0291c40d9f24e8333449b8ecc95040
treef6d3f35affcd3666cb9c6530ff6792164568f370
parent828a5414db01df38bb2ace6034cf64330e776fd9

std.Io.Threaded: fix `fileWriteFileStreaming` error handling

If the `getSize` inside `fileWriteFileStreaming` returns an error, two cases can happen: - If was canceled, it will return 0, which will make the calling function repeat it, in which case the cancellation is lost - If it truly returned an error, it will return 0, in which case the calling function will repeat the call and most likely `getSize` will fail again, resulting in an infinite loop Co-authored-by: Lukas Lalinsky <lukas@lalinsky.com> Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36140 Reviewed-by: mlugg <mlugg@mlugg.co.uk>

1 files changed, 8 insertions(+), 2 deletions(-)

lib/std/Io/Threaded.zig+8-2
......@@ -11230,7 +11230,10 @@ fn fileWriteFileStreaming(
1123011230 var off: std.os.linux.off_t = undefined;
1123111231 const off_ptr: ?*std.os.linux.off_t, const count: usize = switch (file_reader.mode) {
1123211232 .positional => o: {
11233 const size = file_reader.getSize() catch return 0;
11233 const size = file_reader.getSize() catch |err| switch (err) {
11234 error.Canceled => |e| return e,
11235 else => break :sf,
11236 };
1123411237 off = std.math.cast(std.os.linux.off_t, file_reader.pos) orelse return error.ReadFailed;
1123511238 break :o .{ &off, @min(@backingInt(limit), size - file_reader.pos, max_count) };
1123611239 },
......@@ -11579,7 +11582,10 @@ fn fileWriteFilePositional(
1157911582 if (file_reader.pos != 0) break :fcf;
1158011583 if (offset != 0) break :fcf;
1158111584 if (limit != .unlimited) break :fcf;
11582 const size = file_reader.getSize() catch break :fcf;
11585 const size = file_reader.getSize() catch |err| switch (err) {
11586 error.Canceled => |e| return e,
11587 else => break :fcf,
11588 };
1158311589 if (header.len != 0 or reader_buffered.len != 0) {
1158411590 const n = try fileWritePositional(t, file, header, &.{limit.slice(reader_buffered)}, 1, offset);
1158511591 file_reader.interface.toss(n -| header.len);