mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-08-22 07:16:03 +00:00
Address review: split semantics, status note, DM size constraint, vacuous parity test
- Parsing Rule 1 now says 'at most 5 parts' and spells out the Swift maxSplits:4 vs Rust splitn(5) off-by-one, which would otherwise make a splitn(4) implementor reject every valid reference. - Overview gains an explicit Status note: nothing parses, routes, fetches, or renders sticker references yet (reviewer ask on #1544). - Document the 255-byte DM content constraint for maximal-length references, pointing at #784 (Codex P2 thread). - parseAcceptsSonarFfiEncodedContent now #requires the parse result: #expect(ref == makeRef(...)) could pass vacuously as nil == nil. Flagged by the multi-model review panel.
This commit is contained in:
parent
cc63c0c9a7
commit
5960b7f343
@ -51,10 +51,12 @@ struct StickerRefCodecTests {
|
||||
#expect(StickerRefCodec.encode(ref).hasPrefix("\u{1F}sticker\u{1F}"))
|
||||
}
|
||||
|
||||
@Test func parseAcceptsSonarFfiEncodedContent() {
|
||||
@Test func parseAcceptsSonarFfiEncodedContent() throws {
|
||||
// Hand-built exactly as mesh_parse_sticker_content would see it.
|
||||
let wire = "\u{1F}sticker\u{1F}30031:\(pubkey):pack\u{1F}wave\u{1F}\(sha256)"
|
||||
let ref = StickerRefCodec.parse(wire)
|
||||
// #require (not #expect against makeRef): if a regression made parse
|
||||
// return nil here, `nil == nil` would let the test pass vacuously.
|
||||
let ref = try #require(StickerRefCodec.parse(wire))
|
||||
#expect(ref == makeRef(coordinate: "30031:\(pubkey):pack"))
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,19 @@ specifies only the bitchat wire format and client behavior. The reference
|
||||
implementation is byte-identical to sonar-ffi's `mesh_sticker_content` /
|
||||
`mesh_parse_sticker_content`.
|
||||
|
||||
> **Status:** this lands in slices. The wire codec below is merged first as
|
||||
> dead-on-arrival infrastructure — **nothing in the client parses, routes,
|
||||
> fetches, or renders sticker references yet.** Parsing, consent-gated
|
||||
> rendering, and opt-in sync arrive in the follow-up PRs (see the split of
|
||||
> #1517). Until then, sticker content is ordinary text to every client.
|
||||
|
||||
> **DM size constraint:** a maximally long reference (80-char identifier +
|
||||
> 64-char shortcode) is ~290 bytes, which exceeds the current 255-byte
|
||||
> private-message content limit (`PrivateMessagePacket`). Senders SHOULD keep
|
||||
> the encoded reference within 255 bytes for DMs until that limit is raised
|
||||
> (tracked in #784); oversized references remain valid on public mesh and
|
||||
> geohash channels.
|
||||
|
||||
## Wire Format
|
||||
|
||||
### Content Prefix
|
||||
@ -46,8 +59,11 @@ Field order and count are fixed:
|
||||
|
||||
Parsers MUST:
|
||||
|
||||
1. Split the content on `0x1F` with **at most 4 splits**, preserving empty
|
||||
subsequences.
|
||||
1. Split the content on `0x1F` into **at most 5 parts**, preserving empty
|
||||
subsequences. Beware off-by-one semantics across languages: this is
|
||||
Swift's `split(separator:maxSplits:)` with `maxSplits: 4` (4 splits → up
|
||||
to 5 parts), but Rust's `splitn(5, ...)` — `splitn(4, ...)` yields at
|
||||
most 4 parts and would reject every valid reference.
|
||||
2. Accept only if the split yields **exactly 5 parts**, `parts[0]` is empty,
|
||||
and `parts[1] == "sticker"`.
|
||||
3. Validate fields 2–4 against the table above; any violation MUST cause the
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user