From ae0f545a06b63c900b1982d75f15795bb294b327 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 30 Sep 2026 02:39:29 +0200 Subject: [PATCH] Readability vectors: a legacy array with bytes after it Rust's read path let a legacy envelope array with trailing bytes through when the whole-array check was loosened, and no vector caught it. Add the vector; every runtime refuses it. Co-Authored-By: Claude Sonnet 5.5 --- packages/cultcache-py/tests/test_cultcache.py | 2 +- packages/cultcache-rs/src/lib.rs | 2 +- packages/cultcache-ts/test/cult-cache.test.ts | 2 +- tests/vectors/document-variants-c2a/readability/generate.py | 2 ++ .../document-variants-c2a/readability/legacy-trailing.bin | 1 + tests/vectors/document-variants-c2a/readability/manifest.txt | 1 + 6 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 tests/vectors/document-variants-c2a/readability/legacy-trailing.bin diff --git a/packages/cultcache-py/tests/test_cultcache.py b/packages/cultcache-py/tests/test_cultcache.py index 5241ea14..5f74737d 100644 --- a/packages/cultcache-py/tests/test_cultcache.py +++ b/packages/cultcache-py/tests/test_cultcache.py @@ -913,7 +913,7 @@ class CultCacheTests(unittest.TestCase): for line in (root / "manifest.txt").read_text(encoding="utf-8").splitlines() if line and not line.startswith("#") ] - self.assertEqual(len(rows), 14) + self.assertEqual(len(rows), 15) envelopes = SingleFileMessagePackBackingStore(self._C2A_VECTORS / "v3-base.msgpack").pull_all() for vector, _, _, _, python in rows: content = (root / vector).read_bytes() diff --git a/packages/cultcache-rs/src/lib.rs b/packages/cultcache-rs/src/lib.rs index fed9ecdf..ca1d3fba 100644 --- a/packages/cultcache-rs/src/lib.rs +++ b/packages/cultcache-rs/src/lib.rs @@ -4858,7 +4858,7 @@ mod tests { } } } - assert_eq!(rows, 14); + assert_eq!(rows, 15); Ok(()) } diff --git a/packages/cultcache-ts/test/cult-cache.test.ts b/packages/cultcache-ts/test/cult-cache.test.ts index 7235a6c4..9cc187d5 100644 --- a/packages/cultcache-ts/test/cult-cache.test.ts +++ b/packages/cultcache-ts/test/cult-cache.test.ts @@ -1590,7 +1590,7 @@ test("SingleFileMessagePackBackingStore replaces a file exactly when it reads", .split(/\r?\n/u) .filter((line) => line.length > 0 && !line.startsWith("#")) .map((line) => line.split(/\s+/u)); - assert.equal(rows.length, 14); + assert.equal(rows.length, 15); const dir = await mkdtemp(join(tmpdir(), "cultcache-readability-")); const seed = await copyVector(dir, join(c2aVectors, "v3-base.msgpack"), "seed.msgpack"); const envelopes = await new SingleFileMessagePackBackingStore(seed).pullAll(); diff --git a/tests/vectors/document-variants-c2a/readability/generate.py b/tests/vectors/document-variants-c2a/readability/generate.py index bb63d0a9..288862ad 100644 --- a/tests/vectors/document-variants-c2a/readability/generate.py +++ b/tests/vectors/document-variants-c2a/readability/generate.py @@ -17,6 +17,7 @@ vectors = { "empty-array": pack([]), # A legacy envelope array: an array of maps. Rust, TypeScript and Python read it; C# has no legacy reader. "legacy-envelopes": pack([{"key": "old", "type": "old.type", "payload": pack([]), "storedAt": "2026-01-01T00:00:00Z"}]), + "legacy-trailing": None, # filled below: the legacy array plus bytes after it "ints": pack([1, 2, 3]), "nil-first": pack([None, "x"]), "nested-array": pack([["cultcache.store.v9", [], []]]), @@ -28,6 +29,7 @@ vectors = { "trailing-bytes": whole + b"\x01\x02\x03", "trailing-store": whole + whole, } +vectors["legacy-trailing"] = vectors["legacy-envelopes"] + b"" for name, data in vectors.items(): (here / f"{name}.bin").write_bytes(data) print(len(vectors), "vectors") diff --git a/tests/vectors/document-variants-c2a/readability/legacy-trailing.bin b/tests/vectors/document-variants-c2a/readability/legacy-trailing.bin new file mode 100644 index 00000000..37f77fc8 --- /dev/null +++ b/tests/vectors/document-variants-c2a/readability/legacy-trailing.bin @@ -0,0 +1 @@ +‘„£key£old¤type¨old.type§payloadÄ�¨storedAt´2026-01-01T00:00:00Z \ No newline at end of file diff --git a/tests/vectors/document-variants-c2a/readability/manifest.txt b/tests/vectors/document-variants-c2a/readability/manifest.txt index 55e028f9..8675d6b9 100644 --- a/tests/vectors/document-variants-c2a/readability/manifest.txt +++ b/tests/vectors/document-variants-c2a/readability/manifest.txt @@ -4,6 +4,7 @@ zero-byte.bin reads reads reads reads empty-array.bin reads reads reads reads legacy-envelopes.bin refuses reads reads reads +legacy-trailing.bin refuses refuses refuses refuses ints.bin refuses refuses refuses refuses nil-first.bin refuses refuses refuses refuses nested-array.bin refuses refuses refuses refuses