From a7387f0047a1bb67c31e947a251171834a3f9817 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 6 Jul 2025 18:20:11 -0700 Subject: [PATCH] fix std.io.Writer.VectorWrapper mechanism previous implementation erroneously attempted to detect whether vector API was used via the buffer pointer. This implementation has an explicit flag. --- lib/std/io/Reader.zig | 15 +++++++++++---- lib/std/io/Writer.zig | 3 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/std/io/Reader.zig b/lib/std/io/Reader.zig index a9e790a437..914f27d3ef 100644 --- a/lib/std/io/Reader.zig +++ b/lib/std/io/Reader.zig @@ -328,17 +328,24 @@ pub fn readVecLimit(r: *Reader, data: []const []u8, limit: Limit) Error!usize { }; var n = r.vtable.stream(r, &wrapper.writer, .limited(remaining)) catch |err| switch (err) { error.WriteFailed => { + assert(!wrapper.used); if (wrapper.writer.buffer.ptr == first.ptr) { remaining -= wrapper.writer.end; } else { + assert(wrapper.writer.end <= r.buffer.len); r.end = wrapper.writer.end; } break; }, else => |e| return e, }; - if (wrapper.writer.buffer.ptr != first.ptr) { - r.end = n; + if (!wrapper.used) { + if (wrapper.writer.buffer.ptr == first.ptr) { + remaining -= n; + } else { + assert(n <= r.buffer.len); + r.end = n; + } break; } if (n < first.len) { @@ -355,6 +362,7 @@ pub fn readVecLimit(r: *Reader, data: []const []u8, limit: Limit) Error!usize { remaining -= mid.len; n -= mid.len; } + assert(n <= r.buffer.len); r.end = n; break; } @@ -596,12 +604,11 @@ pub fn readSliceShort(r: *Reader, buffer: []u8) ShortError!usize { }; const n = r.vtable.stream(r, &wrapper.writer, .unlimited) catch |err| switch (err) { error.WriteFailed => { - if (wrapper.writer.buffer.ptr != remaining.ptr) { + if (!wrapper.used) { assert(r.seek == 0); r.seek = remaining.len; r.end = wrapper.writer.end; @memcpy(remaining, r.buffer[0..remaining.len]); - return buffer.len; } return buffer.len; }, diff --git a/lib/std/io/Writer.zig b/lib/std/io/Writer.zig index a5cb0aded1..b1d1f78064 100644 --- a/lib/std/io/Writer.zig +++ b/lib/std/io/Writer.zig @@ -390,12 +390,15 @@ pub const WritableVectorIterator = struct { pub const VectorWrapper = struct { writer: Writer, it: WritableVectorIterator, + /// Tracks whether the "writable vector" API was used. + used: bool = false, pub const vtable: VTable = .{ .drain = fixedDrain }; }; pub fn writableVectorIterator(w: *Writer) Error!WritableVectorIterator { if (w.vtable == &VectorWrapper.vtable) { const wrapper: *VectorWrapper = @fieldParentPtr("writer", w); + wrapper.used = true; return wrapper.it; } return .{ .first = try writableSliceGreedy(w, 1) };