Skip to content

ReadUntil discards only headers, not bodies — misparses any stream where the target atom isn't first #182

Description

@kixelated

ReadUntil is documented as "Keep discarding atoms until the desired atom is found", but it only discards headers — it never reads or skips the body of a non-matching atom, so the next iteration parses a "header" out of the middle of the skipped atom's body:

  • src/atom.rs:112-123 (sync):
while let Some(header) = <Option<Header> as ReadFrom>::read_from(r)? {
    if header.kind == T::KIND {
        let body = &mut header.read_body(r)?;
        return Ok(Some(T::decode_atom(&header, body)?));
    }
    // no else: header.size body bytes are never consumed
}
  • src/tokio/atom.rs:56-67 (async) has the identical bug.

Reproduced: for a stream of [free box with 4-byte body "ABCD"][valid ftyp], Option::<Ftyp>::read_until(...) returns Ok(None) — it interprets ABCD… as a header and consumes the rest of the stream as garbage. Any stream where the sought atom is not the first atom (the typical use case for this API) misparses.

Fix: when header.kind != T::KIND, read and discard header.size bytes (or seek forward) before looping.

Found during an extensive automated correctness review (Claude Code); reproduced against the current main sources.

Activity

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions