commit 52730f3f2191aa242b030b9c5f3ca33a7f4fea88 (tree)
parent 6682ff2e85dc528ad2552b23fd540423b0c456bb
Author: whatisaphone <hi@whatisaph.one>
Date: Mon, 1 Sep 2025 10:23:49 -0400
Fix Reader.Limited end of stream conditions
Diffstat:
1 file changed, 44 insertions(+), 0 deletions(-)
diff --git a/lib/std/Io/Reader/Limited.zig b/lib/std/Io/Reader/Limited.zig
@@ -27,6 +27,7 @@ pub fn init(reader: *Reader, limit: Limit, buffer: []u8) Limited {
fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize {
const l: *Limited = @fieldParentPtr("interface", r);
+ if (l.remaining == .nothing) return error.EndOfStream;
const combined_limit = limit.min(l.remaining);
const n = try l.unlimited.stream(w, combined_limit);
l.remaining = l.remaining.subtract(n).?;
@@ -51,8 +52,51 @@ test stream {
fn discard(r: *Reader, limit: Limit) Reader.Error!usize {
const l: *Limited = @fieldParentPtr("interface", r);
+ if (l.remaining == .nothing) return error.EndOfStream;
const combined_limit = limit.min(l.remaining);
const n = try l.unlimited.discard(combined_limit);
l.remaining = l.remaining.subtract(n).?;
return n;
}
+
+test "end of stream, read, hit limit exactly" {
+ var f: Reader = .fixed("i'm dying");
+ var l = f.limited(.limited(4), &.{});
+ const r = &l.interface;
+
+ var buf: [2]u8 = undefined;
+ try r.readSliceAll(&buf);
+ try r.readSliceAll(&buf);
+ try std.testing.expectError(error.EndOfStream, l.interface.readSliceAll(&buf));
+}
+
+test "end of stream, read, hit limit after partial read" {
+ var f: Reader = .fixed("i'm dying");
+ var l = f.limited(.limited(5), &.{});
+ const r = &l.interface;
+
+ var buf: [2]u8 = undefined;
+ try r.readSliceAll(&buf);
+ try r.readSliceAll(&buf);
+ try std.testing.expectError(error.EndOfStream, l.interface.readSliceAll(&buf));
+}
+
+test "end of stream, discard, hit limit exactly" {
+ var f: Reader = .fixed("i'm dying");
+ var l = f.limited(.limited(4), &.{});
+ const r = &l.interface;
+
+ try r.discardAll(2);
+ try r.discardAll(2);
+ try std.testing.expectError(error.EndOfStream, l.interface.discardAll(2));
+}
+
+test "end of stream, discard, hit limit after partial read" {
+ var f: Reader = .fixed("i'm dying");
+ var l = f.limited(.limited(5), &.{});
+ const r = &l.interface;
+
+ try r.discardAll(2);
+ try r.discardAll(2);
+ try std.testing.expectError(error.EndOfStream, l.interface.discardAll(2));
+}