Skip to content

std.Io.Reader.Limited can hang #25093

Closed

Description

@jeffective

Zig Version

0.16.0-dev.70+73a0b5441

Steps to Reproduce and Observed Behavior

  1. create file test.zig with the following contents:
const std = @import("std");

// An unlimited stream of 0xaa bytes.
pub const AAStream = struct {
    reader: std.Io.Reader,

    pub fn init(
        buffer: []u8,
    ) AAStream {
        return AAStream{
            .reader = .{
                .vtable = &.{
                    .stream = AAStream.streamHexAA,
                },
                .buffer = buffer,
                .seek = 0,
                .end = 0,
            },
        };
    }

    fn streamHexAA(io_reader: *std.Io.Reader, w: *std.Io.Writer, limit: std.Io.Limit) std.Io.Reader.StreamError!usize {
        _ = io_reader;

        // Uncomment this line to see that this function is repeatedly called with limit 0.
        // defer std.debug.print("stream function finished. called with limit: {?}\n", .{limit.toInt()});

        const n_bytes_remaining = limit.minInt(2);
        for (0..n_bytes_remaining) |_| {
            try w.writeByte(0xaa);
        }
        return n_bytes_remaining;
    }
};

test {
    var aa_buffer: [1024]u8 = undefined;
    var aa_stream = AAStream.init(&aa_buffer);

    // apply a limit of 2 bytes
    var buffer: [1024]u8 = undefined;
    var limited = std.Io.Reader.limited(
        &aa_stream.reader,
        .limited(2),
        &buffer,
    );
    const reader = &limited.interface;

    // trigger EndOfStream
    var out_buffer: [8]u8 = undefined;
    try std.testing.expectError(error.EndOfStream, reader.readSliceAll(&out_buffer));
}
  1. observe test hanging by running zig test test.zig

Expected Behavior

Test passes.

Activity

  1. added
    bugObserved behavior contradicts documented or intended behavior
    on Aug 31, 2025
  2. added
    standard libraryThis issue involves writing Zig code for the standard library.
    on Sep 2, 2025
  3. added this to the 0.15.2 milestone on Sep 2, 2025
  4. eestrada commented on Sep 5, 2025

    @eestrada

    I think I may have hit this bug when I attempted to use a Reader.Limited instance and then stream to a writer using streamRemaining. I ran it through a debugger and found that it just kept returning zero instead of error.EndOfStream, so it stayed in an endless loop attempting to stream more bytes and just reporting that it streamed zero bites every time after it had streamed up to its limit.

    Here is what I did to work around it for the time being: skip using a Reader.Limited instance altogether and just use the streamExact function on the original reader instead. This may not work for all circumstances, but it was acceptable for mine.

    This was for zig stable version 0.15.1

  5. modified the milestones: 0.15.2, urgent on Sep 30, 2025
  6. modified the milestones: urgent, 0.15.2 on Oct 7, 2025
  7. andrewrk commented on Oct 7, 2025

    @andrewrk
    Member

    Fix reverted in b824ca8

  8. whatisaphone commented on Oct 9, 2025

    @whatisaphone
    Contributor

    I ran OP's code after #25512 (on 529aa9f) and it no longer hangs. This can be closed!

  9. andrewrk commented on Oct 9, 2025

    @andrewrk
    Member

    Thanks for checking!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorstandard libraryThis issue involves writing Zig code for the standard library.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions