Skip to content

tick decode: step over a tick too wide to read, rather than dropping the message (ibx#302) - #358

Open
userFRM wants to merge 1 commit into
deepentropy:mainfrom
userFRM:fix/extended-tick-width
Open

tick decode: step over a tick too wide to read, rather than dropping the message (ibx#302)#358
userFRM wants to merge 1 commit into
deepentropy:mainfrom
userFRM:fix/extended-tick-width

Conversation

@userFRM

@userFRM userFRM commented Jul 30, 2026

Copy link
Copy Markdown

Summary

  • An extended 35=P entry states its width in a full byte, so it can name a value wider than this decoder returns. The decoder abandoned the whole message at that point, so every tick after it went with it — including the other server tags in the same message.
  • The field is now stepped over and decoding continues. The entry itself is still dropped rather than guessed at, and a genuinely truncated message still ends where it did.

Why

A quote update sitting behind one of these simply never arrived, and nothing recorded that it had. One entry the decoder cannot represent should cost that entry, not the rest of the message.

Closes #302.

Notes

Stepping over needs a skip on the bit reader. Its width comes off the wire, so it is bounded by what is actually left rather than by an addition that wraps in release and rewinds the reader instead of stopping it. It is private — only this decoder steps.

The test payload builder gained the ability to emit a field wider than a u64, which is what building one of these requires.

Test plan

  • cargo test --offline --lib — 804 passed. The 2 failures are config::expiry_tests::{named_zone_converts_with_dst, instant_round_trips_to_wire}, which fail on the base commit too (fixed separately in config: resolve the legacy timezone names IB states its times in (ibx#335) #336).
  • cargo check --offline clean on every target: --lib, --features python, --bins, --examples, and each of the eight tests/*.rs targets individually.
  • tests/ib_paper_compat unchanged from base — identical sorted diagnostic sets, not merely equal counts.
  • Mutation check: restoring the bare return fails a_tick_too_wide_to_read_does_not_discard_the_rest_of_the_message; making skip add unchecked fails skipping_past_the_end_refuses_rather_than_wrapping. Both by name.
  • The test asserts the ticks after the wide entry and the whole server tag after it, so it distinguishes "kept going" from "stopped one entry later".

🤖 Generated with Claude Code

…the message

An extended entry states its width in a full byte, so it can name a value wider than this decoder returns. That entry is lost either way — but the decoder abandoned the whole message at that point, so every tick after it went with it, including the other server tags in the same 35=P. A quote update sitting behind one simply never arrived, and nothing recorded that it had.

The field is now stepped over and decoding continues. The entry itself is still dropped rather than guessed at, and a genuinely truncated message still ends where it did.

Stepping over needs a `skip` on the bit reader. Its width comes off the wire, so it is bounded by what is actually left rather than by an addition that wraps in release and rewinds the reader instead of stopping it. It is private: only this decoder steps.

The test payload builder gained the ability to emit a field wider than a `u64`, which is what building one of these requires.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tick decode: an extended tick with a width above 8 silently discards the rest of the 35=P message

1 participant