Skip to content

refuse to encode a 1033 frame the package cannot parse - #588

Closed
aashish254 wants to merge 1 commit into
meta:mainfrom
aashish254:fix/encode1033-frame-length-limits
Closed

aashish254 wants to merge 1 commit into
meta:mainfrom
aashish254:fix/encode1033-frame-length-limits

Conversation

@aashish254

@aashish254 aashish254 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

rtcm.Encode1033 takes an AntennaDescriptor of caller-supplied strings and writes their lengths into
the frame without checking either width limit the format imposes. Two consequences on main, both measured:

The payload can exceed the 10-bit length field. The header is preamble + 6 reserved zero bits + a
10-bit length (MaxPayloadLen = 1023), but payloadSize is built straight from len(desc.*) and then
written with binary.BigEndian.PutUint16(frame[1:3], uint16(len(payload)&0xFFFF)). With five 250-byte
descriptor fields the encoder returns a 1265-byte frame whose header reads d3 04 eb: 0x4 sits in the
reserved bits (frame[1] & 0xFC == 0x4) and the length the rest of the package reads back is 235, not 1259.
The same package then rejects its own output:

ParseFrame(frame) -> err = CRC-24Q mismatch: computed 0x6DD303, expected 0x414141
NewScanner(reader) -> frames delivered = 0

So ntripper, which injects a 1033 on connect and every 30s, would hand a caster a frame its own scanner
can't even resynchronise past.

A descriptor string longer than 255 bytes silently lies about itself. DF227/DF230/DF232/DF234/DF236 are
8-bit counters, and the encoder writes uint8(len(...)). For a 300-byte AntennaType the frame declares a
44-byte field, so a conformant parser reads 44 bytes and treats the remaining 256 as the next fields —
corrupt payload, valid CRC, no error anywhere on the read path.

What changed

  • Encode1033 now returns ([]byte, error) and rejects both cases up front: ErrDescriptorTooLong (new)
    for a string over maxDescriptorFieldLen, ErrPayloadTooLarge (already the package's word for exactly
    this, raised by ParseFrame at rtcm.go:93 and by msm_encode.go:548) for a total that doesn't fit the
    header. This matches how msm_encode.go already signals the same class of overflow instead of emitting a
    frame the parser rejects.
  • The header write is now the explicit two bytes of the 10-bit field (frame[1] = len>>8 & 0x03) so the
    reserved bits can't be loaded again. To be clear, this line is equivalent to PutUint16 for every
    length the guards now allow, so it isn't a second fix — it just makes the invariant the old line broke
    visible where it broke.
  • The production caller (cmd/ntripper/streamFrames) wraps the error, and the existing test call sites go
    through a mustEncode1033 helper.

Verification

  • New TestEncode1033RejectsUnrepresentableFrames covers both rejection paths, including a case where
    every field is individually legal but their sum is not.
  • New TestEncode1033LargestRepresentableFrame builds the longest frame the header can still describe
    (255+255+255+249 descriptor bytes + 9 bytes overhead = exactly MaxPayloadLen), asserts the reserved bits
    stay zero, and round-trips it through both ParseFrame and NewScanner — the encoder and the package's
    own readers now agree at the boundary.
  • Mutation-checked each guard separately: deleting the payload-size check fails only the "total exceeds the
    10-bit header length" subtest, deleting the per-field loop fails only "field exceeds its 8-bit counter".
    Neither guard is carried by the other.
  • go test -count=1 ./rtcm/... ./cmd/ntripper/..., go test -race ./rtcm/... ./cmd/ntripper/...,
    go vet, gofmt -l and golangci-lint run (repo .golangci.yml) all clean.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 20, 2026
@meta-codesync

meta-codesync Bot commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

@leoleovich has imported this pull request. If you are a Meta employee, you can view this in D126438243.

@meta-codesync meta-codesync Bot closed this in beb208d Oct 21, 2026
@meta-codesync meta-codesync Bot added the Merged label Oct 21, 2026
@meta-codesync

meta-codesync Bot commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

@leoleovich merged this pull request in beb208d.

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

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant