protocol: compare the NS prefix in place rather than through an uppercased copy (ibx#365) - #366
Open
userFRM wants to merge 1 commit into
Open
protocol: compare the NS prefix in place rather than through an uppercased copy (ibx#365)#366userFRM wants to merge 1 commit into
userFRM wants to merge 1 commit into
Conversation
userFRM
force-pushed
the
fix/ns-prefix-slice-panic
branch
2 times, most recently
from
July 30, 2026 12:06
f8d6f05 to
7f2a300
Compare
…cased copy `ns_parse` uppercased the payload to test for a "MISC" prefix, then sliced the original at byte 4. Uppercasing is not length-preserving: U+0131 and U+017F each occupy two bytes and uppercase to one ASCII byte, so a payload whose first four characters uppercase to "MISC" while occupying more than four bytes passed the check with byte 4 inside a character, and slicing a `&str` there panics. The prefix is now compared in place against an ASCII "MISC", and the remainder is taken with a checked slice. The framed receive path does not reach that panic — `is_ns_text` admits only an ASCII digit or a literal "MISC" before dispatching here — so this hardens the parser for callers that hold it directly rather than closing a live crash. The behaviour change is confined to the panic. The old code also recognised non-ASCII spellings, but it removed four bytes and each of those characters occupies two, so such a payload either put byte 4 inside a character or shifted the cut so the remainder began mid-prefix and failed to parse. None of them ever parsed. Also drops an allocation per inbound NS message on that path. Closes deepentropy#365.
userFRM
force-pushed
the
fix/ns-prefix-slice-panic
branch
from
July 30, 2026 16:42
7f2a300 to
c6798bf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ns_parseuppercased the payload to test for aMISCprefix, then sliced the original at byte 4.Uppercasing is not length-preserving:
U+0131andU+017Feach occupy two bytes and uppercase to one ASCII byte. So a payload whose first four characters uppercase toMISCwhile occupying more than four bytes passed the check with byte 4 inside a character, and slicing a&strthere panics.Scope
The framed receive path does not reach it.
is_ns_textadmits only an ASCII digit or a literalMISCbefore dispatching here, so this hardens the parser for callers that hold it directly rather than closing a live crash.What this changes
The prefix is compared in place against an ASCII
MISC, and the remainder is taken with a checked slice.The behaviour change is confined to the panic. The old code also recognised non-ASCII spellings, but it removed four bytes and each of those characters occupies two — so such a payload either put byte 4 inside a character, or shifted the cut so the remainder began mid-prefix and failed to parse. None of them ever parsed.
Also drops an allocation per inbound NS message on that path.
Tests
a_prefix_that_changes_length_when_uppercased_does_not_panic— the hostile spellings plus the short and empty shapes. Fails by name against the previous parser.a_genuine_misc_prefix_is_still_stripped— the positive control, in any ASCII casing.the_prefix_is_an_ascii_misc_and_nothing_elseandstripping_leaves_the_defined_shapes_alone— pin the boundary the prefix rule draws. Both agree with the previous behaviour, which is the point; the guard for the change is the panic test.Closes #365.
Test plan
a_prefix_that_changes_length_when_uppercased_does_not_panicby name.a_genuine_misc_prefix_is_still_stripped, in any ASCII casing.the_prefix_is_an_ascii_misc_and_nothing_elseandstripping_leaves_the_defined_shapes_alonepin the boundary the prefix rule draws; both agree with the previous behaviour, which is the point.cargo check --offlineclean on--lib,--lib --features python,--bins,--examples, and each integration target individually.tests/ib_paper_compatcompared against a clean checkout of the base commit — identical sorted diagnostic sets.cargo test --offline --lib— only the two knownconfig::expiry_testsfailures, which fail on the base commit for missing legacy tzdata (fixed separately in config: resolve the legacy timezone names IB states its times in (ibx#335) #336).