v1.0.4
Release Version 1.0.4
Highlights
- Cross-module type headers: Normalizes
Swift/Foundation/FoundationEssentialsqualifiers in generic wire type names so equivalent stdlib types decode reliably across toolchains. - Untrusted-input hardening: Optional decode limits reduce DoS risk from malicious length fields.
- Regression tests: Broad coverage for normalization, spacing variants, and limit behavior.
New
BinaryDecodingLimits
Configurable caps for decoding (see BinaryDecoder.init(limits:)):
| Limit | Purpose |
|---|---|
maximumInputByteCount |
Reject oversized Data before parsing |
maximumTypeHeaderUTF8ByteCount |
Cap wire type-name UTF-8 length (always enforced) |
maximumStringUTF8ByteCount |
Cap declared UTF-8 length per string |
maximumDataByteCount |
Cap declared byte length per Data value |
maximumCollectionElementCount |
Cap dictionary key count and array element count |
Presets
BinaryDecodingLimits.default— prior openness for trusted payloads, with a 256 KiB cap on the type-name header.BinaryDecodingLimits.recommendedForUntrustedInput— starting profile for peer/untrusted blobs (tune per protocol).
BinaryDecoder
public init(limits: BinaryDecodingLimits = .default)
Existing BinaryDecoder() call sites remain valid.
Fixed
- Module splits: Fewer spurious
typeMismatcherrors when the same logical type reflects asFoundation.*vsFoundationEssentials.*(and related stdlib spellings). - Generic whitespace: Type identity comparison ignores insignificant spaces in generic lists (e.g.
Dictionary<A,B>vsDictionary<A, B>). - Misconfiguration: Negative optional limits are treated as unset; negative type-header cap falls back to the safe default (
262_144).
Security & robustness
- Decode limits help mitigate allocation / work amplification from untrusted inputs; they are not a substitute for MAC/signature or transport security.
- README Security section updated with guidance on signing, encryption, replay handling, and how limits fit in.
Tests
- Added regression tests for:
- Forged/alternate wire headers (
FoundationEssentials, nested generics) - Dictionary header spacing variants
- All limit fields and negative-limit behavior
- Type mismatch messages referencing normalized identity
- Forged/alternate wire headers (
Compatibility
- Wire format: Unchanged for valid payloads produced by existing encoders.
- API: Backward compatible for typical
BinaryDecoder()usage. - Behavior: Some invalid or pathological inputs may fail earlier or with clearer errors due to stricter checks.
Upgrade notes
For data from untrusted sources, prefer:
let decoder = BinaryDecoder(limits: .recommendedForUntrustedInput)