fix(interop)!: reject double-dot interop segments (LAB-5906) - #164
Conversation
The interop segment pattern admits `..` inside a segment (`a..b`), but the CachekitIO server rejects `..` anywhere in a key (protocol spec/cache-key-format.md#server-side-requirements, Traversal row), so such a key failed with 400 on every request while working on other backends. validateInteropSegment now throws ConfigurationError for a namespace or operation containing `..`, after the grammar check, on every backend. A lone `.` stays valid. The WrapOptions.interop JSDoc states the rule. Re-vendors test-vectors/interop-mode.json 1.2.0 byte-for-byte from cachekit-io/protocol#94 (sha256 702613766d1b92bc3a337627a96b9aedc89abfeb4d9208c2bb00c9539a0a1f40; 35 key / 13 error vectors) and updates the sha and count pins. BREAKING CHANGE: an interop namespace or operation containing `..` now throws ConfigurationError at wrap time, on every backend. Rename the segment; its keys become a full cache miss.
|
Warning Review limit reachedNext included review available in 23 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: cachekit-io/cachekit-ts/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Code Review Completed! 🔥The code review was successfully completed based on your current configurations. Kody Guide: Usage and ConfigurationInteracting with Kody
Providing Context (Files & MCPs)Add these hints in your PR description (or a comment) to unlock deeper checks:
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Code Review Completed! 🔥The code review was successfully completed based on your current configurations. Kody Guide: Usage and ConfigurationInteracting with Kody
Providing Context (Files & MCPs)Add these hints in your PR description (or a comment) to unlock deeper checks:
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
Summary
Interop segments (namespace and operation) containing
..are now rejected at wrap time on all backends. The interop/v1 grammar^[a-z0-9][a-z0-9._-]{0,63} allows such segments, but the CachekitIO server rejects..anywhere in a key. Before this change the SDK could produce a key that returned400` on every CachekitIO request while still working on other backends.Public API changes
validateInteropSegment(kind, value)(serialization/interop.ts)ConfigurationErrorwhenvaluecontains.....check, then the reserved-namespace (ns/nsapi) check.Invalid interop <kind> "<value>": must not contain '..' — the CachekitIO server rejects '..' anywhere in a key.@throwsJSDoc lists the new condition..is still valid, including a trailing one (e.g.app.).cache.wrapwithinteropvalidateInteropSegment, so it throws for a..namespace or operation.generateInteropKeyalso goes through this validation path.WrapOptions.interopJSDoc (types/cache.ts, shipped in.d.ts) now states that neither segment may contain..and that a single.is allowed.Because
:delimits segments and the hash is hex, any..in a full key must fall inside a segment. Validating the segments is therefore enough to prevent server-side traversal rejections.Tests and fixtures
cache.interop.test.tswrapthrows for namespacea..band for operationx..y.app.with operationusers.fetch.by_id(arity 1) writes exactly the pinned keyapp.:users.fetch.by_id:405f09a3…e21a, matching thelone_dots_stay_validvector.interop-mode.protocol.test.tsinterop-mode.json1.2.0 (fix(interop)!: forbid double-dot inside interop segments (LAB-5906) protocol#94).FIXTURE_SHA256is updated to702613766d1b…1f40..secrets.baseline: only line-number shifts for existing fixture entries and a newgenerated_attimestamp. No new secrets.Breaking change
Any existing interop namespace or operation containing
..now fails withConfigurationErrorat wrap time. Such segments must be renamed, and keys under the new name start as a full cache miss.Summary
Updates the JSDoc for the public
generateInteropKey()function inpackages/cachekit/src/serialization/interop.ts. The documentation now states that aConfigurationErroris thrown whennamespaceoroperationcontains.., in addition to the existing cases (segment-grammar violations and the reserved namespacesnsandnsapi).Public API
generateInteropKey(): The@throws {ConfigurationError}contract now explicitly covers segments containing... The function signature is unchanged.Notes
... Such enforcement may already exist elsewhere, for example in the segment-grammar check, or it may be missing from this diff.!). Callers who currently pass namespace or operation values containing..should expect aConfigurationErroronce the documented behavior is enforced.Summary
The interop/v1 segment pattern admits
..inside a segment (a..b), but the CachekitIO server rejects..anywhere in a key (cache-key-format.md → Server-Side Requirements, the Traversal row). So this SDK accepted such a segment and minted a key that fails with400on every CachekitIO request, while the same key works on other backends. cachekit-io/protocol#94 forbids..in either segment; this PR implements it.Changes
validateInteropSegment(packages/cachekit/src/serialization/interop.ts) throwsConfigurationErrorfor a namespace or operation containing.., after the grammar check, on every backend.generateInteropKeyandcache.wrapboth go through it. A lone.stays valid, including at the end of a segment.interop-mode.json1.2.0 byte-for-byte from cachekit-io/protocol#94 (sha256702613766d1b92bc3a337627a96b9aedc89abfeb4d9208c2bb00c9539a0a1f40; 35 key / 13 error vectors) and updates the sha and count pins. The new vectors arereject_double_dot_namespace(a..b),reject_double_dot_operation(x..) andlone_dots_stay_valid(app./users.fetch.by_id).WrapOptions.interopJSDoc (types/cache.ts, shipped in.d.ts) states the rule.src/cache.interop.test.ts(wrap throws for a..namespace and operation; namespaceapp.with operationusers.fetch.by_idwrites thelone_dots_stay_validkey), and the vector suite's sha and count pins (test/protocol/interop-mode.protocol.test.ts)..secrets.baseline: fixture line numbers shift; no new entries.Merge order
Merge cachekit-io/protocol#94 first. The vendored fixture must stay byte-identical to
test-vectors/interop-mode.jsonat its merge commit (sha256 above).Breaking
An interop namespace or operation containing
..now throwsConfigurationErrorat wrap time, on every backend. Rename the segment; its keys become a full cache miss. Before this change, such a key already failed on CachekitIO.Release notes read the breaking note from this block:
BEGIN_COMMIT_OVERRIDE
fix(interop)!: reject double-dot interop segments (LAB-5906) (#164)
BREAKING CHANGE: an interop namespace or operation containing
..now throwsConfigurationErrorat wrap time, on every backend; the exportedgenerateInteropKeythrows it at call time. Rename the segment; its keys become a full cache miss.END_COMMIT_OVERRIDE
Test plan
pnpm lint,pnpm format:check,pnpm type-check,pnpm type-check:testspnpm vitest runinpackages/cachekit: 1184 passed, 1 skippedreject_double_dot_*vectors and the wrap-time test fail