Commit 9abc3232a8

Andrew Kelley <andrew@ziglang.org>
2025-07-21 07:31:49
std.fs.File.Reader: fix missed advance writer positions
1 parent f97c91d
Changed files (3)
lib/std/fs/File.zig
@@ -1430,7 +1430,7 @@ pub const Reader = struct {
                     return error.EndOfStream;
                 }
                 r.pos += n;
-                return n;
+                return w.advanceVector(n);
             },
             .streaming_reading => {
                 if (is_windows) {
@@ -1453,7 +1453,7 @@ pub const Reader = struct {
                     return error.EndOfStream;
                 }
                 r.pos += n;
-                return n;
+                return w.advanceVector(n);
             },
             .failure => return error.ReadFailed,
         }
lib/std/fs/test.zig
@@ -2071,3 +2071,33 @@ test "invalid UTF-8/WTF-8 paths" {
         }
     }.impl);
 }
+
+test "read file non vectored" {
+    var tmp_dir = std.testing.tmpDir(.{});
+    defer tmp_dir.cleanup();
+
+    const contents = "hello, world!\n";
+
+    const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true });
+    defer file.close();
+    {
+        var file_writer: std.fs.File.Writer = .init(file, &.{});
+        try file_writer.interface.writeAll(contents);
+        try file_writer.interface.flush();
+    }
+
+    var file_reader: std.fs.File.Reader = .init(file, &.{});
+
+    var write_buffer: [100]u8 = undefined;
+    var w: std.Io.Writer = .fixed(&write_buffer);
+
+    var i: usize = 0;
+    while (true) {
+        i += file_reader.interface.stream(&w, .limited(3)) catch |err| switch (err) {
+            error.EndOfStream => break,
+            else => |e| return e,
+        };
+    }
+    try std.testing.expectEqualStrings(contents, w.buffered());
+    try std.testing.expectEqual(contents.len, i);
+}
lib/std/Io/Writer.zig
@@ -440,7 +440,8 @@ pub fn advance(w: *Writer, n: usize) void {
 /// After calling `writableVector`, this function tracks how many bytes were
 /// written to it.
 pub fn advanceVector(w: *Writer, n: usize) usize {
-    return consume(w, n);
+    if (w.vtable != VectorWrapper.vtable) advance(w, n);
+    return n;
 }
 
 /// The `data` parameter is mutable because this function needs to mutate the