Fix TcfCaV1 (Canada) OptimizedRange encoding to use Fibonacci, with backwards-compatible decoding#105
Open
chuff wants to merge 4 commits into
Open
Fix TcfCaV1 (Canada) OptimizedRange encoding to use Fibonacci, with backwards-compatible decoding#105chuff wants to merge 4 commits into
chuff wants to merge 4 commits into
Conversation
The Canada (TcfCaV1) VendorExpressConsent, VendorImpliedConsent, and DisclosedVendors fields are OptimizedRange per the spec, which is Fibonacci-coded in GPP. They were using EncodableOptimizedFixedRange (the legacy OptimizedIntRange used by TCF EU); switch them to the existing EncodableOptimizedFibonacciRange. Regenerate the affected test vectors (only populated-vendor cases change; empty/bitfield cases are encoder-agnostic) and add a round-trip test that exercises the Fibonacci range path with sparse vendor IDs. mvn test: 365 tests, 0 failures. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per the GPP spec, PubRestrictions is N-ArrayOfRanges(6,2) where each record's ids are an OptimizedRange (Fibonacci coded). It was using EncodableArrayOfFixedIntegerRanges, which encodes ids as fixed-integer ranges (the legacy ArrayOfRanges form shared with TCF EU). Add EncodableArrayOfOptimizedFibonacciRanges, which reuses the existing EncodableOptimizedFibonacciRange / OptimizedFibonacciRangeEncoder for each record's ids, and point TcfCaV1's PUB_RESTRICTIONS field at it. The fixed variant is left untouched for TCF EU. Regenerate the affected TcfCaV1Test vectors and extend the round-trip test to cover PubRestrictions with sparse ids (Fibonacci range path). Note: verified by Java/ES cross-implementation agreement and round-trip, not yet against an external reference string. mvn test: 365 tests, 0 failures. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Strings produced by the pre-fix encoder used fixed-integer ranges for the OptimizedRange / N-ArrayOfRanges fields (VendorExpressConsent, VendorImpliedConsent, DisclosedVendors, PubRestrictions). Decoding those with the new Fibonacci datatypes would misread the data. The TcfCaV1 core and disclosed-vendors segments now decode by trying the spec-compliant (Fibonacci) interpretation first and, if it does not round-trip back to the input bitstring, falling back to the legacy (fixed-range) interpretation. Whichever re-encodes to the original bits is the one that produced the string. Decoded values are copied into the current (Fibonacci) fields, so the in-memory representation is identical regardless of which encoder produced the string. Tests: decode real pre-fix strings (vendors, PubRestrictions) and assert correct values. mvn test: 367 tests, 0 failures. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…iant Adds a regression test using a real pre-fix (fixed-range) TcfCaV1 string: verifies it decodes correctly (CmpId, language, 14 express + 46 implied vendors) and that re-encoding emits the spec-compliant Fibonacci form. mvn test: 368 tests, 0 failures. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2 tasks
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.
Summary
Per the GPP Consent String Specification, the Canada (
TcfCaV1) section encodes several fields asOptimizedRange/N-ArrayOfRanges, both of which use Fibonacci coding. They were using fixed-integer encoders. This corrects the encoding and keeps existing strings decodable.Fixes:
VendorExpressConsent,VendorImpliedConsent,DisclosedVendors(OptimizedRange) —EncodableOptimizedFixedRange→EncodableOptimizedFibonacciRange.PubRestrictions(N-ArrayOfRanges(6,2), whoseidsare anOptimizedRange) — newEncodableArrayOfOptimizedFibonacciRangesthat reuses the existing FibonacciOptimizedRangefor each record's ids. The fixed variant is left untouched for TCF EU, which legitimately keeps the legacy encoding.(Base64 was already correct in this library — all
TcfCaV1segments use the compressed encoder. The traditional-vs-compressed issue only affected iabgpp-es.)Backwards compatibility
The
TcfCaV1core and disclosed-vendors segments decode by trying the spec-compliant (Fibonacci) interpretation first and, if it doesn't round-trip back to the input bitstring, falling back to the legacy (fixed-range) interpretation. Strings produced by the previous encoder still decode correctly. Empty / bitfield-form data encodes identically either way, so only populated range-form data changes on the wire.Note: this is backwards compatible on read (new code reads old strings). The encoder now emits Fibonacci strings, so consumers still running the previous code will not read the new range-form output — it is a deliberate wire-format correction for the affected fields.
Test plan
mvn test— full suite passes (368 tests)🤖 Generated with Claude Code