Repository navigation
fix(firestore): reject non-canonical paths in Reference JSON codec - #147
Open
detail-app[bot] wants to merge 2 commits into
Open
detail-app[bot] wants to merge 2 commits into
detail-app[bot] wants to merge 2 commits into
Conversation
|
This branch has not been deployed
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.
Detail bug report: View on Detail
Bug
The
referenceChecksfilters inpackages/effect-firebase/src/lib/firestore/schema/reference.tsdisagreed on what a path segment is. Filter 1 (isPathValid) elided empty segments viapath.split('/').filter(Boolean), so it accepted non-canonical paths likeusers/doc123/,/users/abc/posts/def, orposts//1. Filter 2 then read the last segment with the un-filteredpath.split('/').pop(), which yields''for a trailing slash.On the
toCodecJson(ReferenceInstance)codec (and the bareReferenceclass decode) this produced contradictory validation:{ id:'', path:'users/doc123/' }was admitted (a malformed path accepted only because the empty id happened to match the trailing-slashpop()).{ id:'doc123', path:'users/doc123/' }was rejected withId must match the last part of the path, blaming a correctidwhenpathwas the malformed field.This contradicts the library's shared, tested
validateDocPathcontract (path.ts), which rejects every empty-segment path and is used by the admin/client/mock backends. The divergence was exposed whendb21434applied the pre-existing contradictory filter pair to the codec's decode path.Fix
Filter 1 now reuses
validateDocPath(path) === undefined(imported from../path.js) instead of the localisPathValid, so empty-segment paths are rejected consistently with the rest of the library. The message string is kept verbatim ("Path must not be empty and must contain an even number of parts"), so existing regex assertions still match.The local
isPathValidis deliberately left unchanged becauseReference.makeFromPathuses it as its guard — its leading/trailing/consecutive-slash normalization is tested contract (reference.spec.ts) that must keep working. On every path that passes the tightened filter 1,path.split('/').pop()is the real last segment, so filter 2 needs no change regardless of ordering.Closes #138
Testing
referenceChecks.regression.spec.tspinning the previously-untested empty-segment branch ofreferenceCheckson both decode surfaces: the codec now rejects{ id:'', path:'users/doc123/' },{ id:'doc123', path:'users/doc123/' }(with/even number of parts/, not the misleading id error), and{ id:'def', path:'/users/abc/posts/def' }; the bare class decode also rejects{ id:'', path:'users/doc123/' }.isPathValidform: the four rejection tests fail exactly as described above (three accepted instead of throwing; the correct-id case threw the misleadingId must match…error), then pass again after restoring the fix.makeFromPathstill normalizesusers/abc/,/users/abc/posts/def, andusers//abcto canonical form (existingreference.spec.tsnormalization tests, unchanged).effect-firebaseunit tests (370 across 16 spec files), packagebuildandtypecheck, ESLint and Prettier on both changed files, whole-workspacebuild(8 projects), downstream package tests (nx run-many -t test, 121 tests across admin/client/mock/devtools/examples), and the CI matrixnx affected -t lint typecheck test build.parentchain viamakeFromPath, while the bare class decode constructs from the struct fields (no implicitparent).Automatic Fixes PRs can be configured here.