Skip to content

python: strict receiver validation per BBQr BIP draft - #21

Open
scgbckbone wants to merge 3 commits into
coinkite:masterfrom
scgbckbone:bip-compat
Open

scgbckbone wants to merge 3 commits into
coinkite:masterfrom
scgbckbone:bip-compat

Conversation

@scgbckbone

Copy link
Copy Markdown
Contributor

Negative vector: lowercase-hex-body
Frame: B$HT0100aa
Behavior before: bytes.fromhex() accepts lowercase (and whitespace), so the
frame decoded
Fixed by: uppercase-only charset check on H bodies
────────────────────────────────────────
Negative vector: noncanonical-base32-pad-bits
Frame: B$2P0100AB
Behavior before: b32decode() silently discards the non-zero pad bits; AB
decoded to the same byte as canonical AA
Fixed by: re-encode round-trip comparison after decode
────────────────────────────────────────
Negative vector: deflate-trailing-data
Frame: B$ZP0100JNGEUBQAAA
Behavior before: bytes after the DEFLATE end-of-stream marker were silently
ignored
Fixed by: z.unused_data must be empty
────────────────────────────────────────
Negative vector: empty-body
Frame: B$HT0100
Behavior before: header with no body decoded to an empty transfer
Fixed by: body must be non-empty; decoded transfer must be non-empty

The remaining 10 negative vectors (zero total, index ≥ total, unknown
encoding, odd hex length, invalid Base32 terminal length, missing frame,
mixed headers, conflicting duplicate, zlib wrapper, etc.) were already
rejected — unchanged.

Also tightened, per draft rules that have no published vector:

  • strict header grammar: file type must be one uppercase letter, count/index
    must be uppercase base-36 digits (int(x, 36) previously accepted lowercase)
  • non-final bodies must share one length and the final body must not be
    longer (the independent-placement invariant the format relies on)
  • a Z stream must reach its end-of-stream marker — a truncated stream
    previously returned partial data without any error (z.eof check)

@scgbckbone

Copy link
Copy Markdown
Contributor Author

4de2b5d applies the same DEFLATE hardening as #22 (1k-chunked inflate with size cap enforced while inflating, decoded-size cap, join_qrs(parts, max_size=...) override) and commits the BIP vector tests: python/tests/test_vectors.py — 3721 passed.

@scgbckbone

Copy link
Copy Markdown
Contributor Author

3293ab5: exact 1k window via a validate-only pure-python DEFLATE distance scan (CPython zlib compiles out INFLATE_STRICT, no dmax access), boundary tests (1024 accepted, 1025/2048 rejected), vectors re-synced to draft v4 with conflicting-duplicate under strict_policy_cases. 3722 tests pass.

Comment thread python/bbqr/utils.py
return encoding, data, 8

def decode_data(parts, encoding):
def scan_deflate_distances(stream, max_dist=1024):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like overkill

This branch has not been deployed

No deployments
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.

1 participant