diff --git a/lib/std/Io/Reader/Limited.zig b/lib/std/Io/Reader/Limited.zig index c2e9ee2f49..5d87200869 100644 --- 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)); +}