fix(postgrest): escape " and \ inside quoted filter values - #2529
fix(postgrest): escape " and \ inside quoted filter values#2529PedroHenrique0713 wants to merge 1 commit into
Conversation
Six filter methods in PostgrestFilterBuilder wrapped values with reserved
chars (,()) in double quotes but never escaped inner " or \ per
PostgREST's backslash convention. Two distinct symptoms:
1. in()/notIn(): a value containing both a reserved char and a double
quote produced a broken quoted string — e.g. in.("a"b,c") — that
PostgREST cannot parse. Now escapes " as \" and \ as \\, producing
in.("a\\"b,c") which PostgREST parses correctly.
2. likeAllOf/likeAnyOf/ilikeAllOf/ilikeAnyOf(): patterns were joined with
, without any quoting. A pattern containing a comma was silently split
by PostgREST into multiple patterns — e.g. like(all).{%foo,bar%} became
two patterns %foo and bar%. Now quotes patterns that contain reserved
chars, with the same backslash escaping for " and \.
PostgREST docs:
https://postgrest.org/en/stable/references/api/url_grammar.html#reserved-characters
Validated E2E against a real PostgREST server (Supabase CLI local, port
54321): 8/8 tests pass. tsc clean, prettier clean.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughSummary by CodeRabbit
Walkthrough
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. 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 |
🔍 Description
What changed?
Six filter methods in
PostgrestFilterBuildernow correctly escape"and\inside quoted filter values, per PostgREST's backslash convention:in()/notIn(): values that contain both a reserved char (,()``) and a"or` are now escaped as\"and\\inside the wrapping double quotes.likeAllOf()/likeAnyOf()/ilikeAllOf()/ilikeAnyOf(): patterns that contain a reserved char are now wrapped in double quotes (previously they were not quoted at all), with the same\"/\\escaping.The stale comment link was also updated to the current PostgREST docs (
/en/stable/references/api/url_grammar.html#reserved-characters).Why was this change needed?
PostgREST's URL grammar treats
,,.,:,()as reserved characters. When a filter value contains one of these, it must be wrapped in double quotes%22...%22. Inside those quotes,"is escaped with a backslash\"and\with\\— not CSV-style doubling"".Bug 1 —
in()/notIn(): the old code wrapped values in"..."when they contained a reserved char, but never escaped an inner". So.in("col", ["a\"b,c"])producedin.("a"b,c"), which PostgREST cannot parse (the quote terminates the value early). Affected any value with both a reserved char and a literal double quote.Bug 2 —
likeAllOf/likeAnyOf/ilikeAllOf/ilikeAnyOf: the old code didpatterns.join(",")with no quoting at all. A pattern containing a comma was silently split by PostgREST into multiple patterns —.likeAllOf("col", ["%foo,bar%"])producedlike(all).{%foo,bar%}which PostgREST reads as two patterns (%fooandbar%), matching the wrong rows or nothing.PostgREST docs: https://postgrest.org/en/stable/references/api/url_grammar.html#reserved-characters
📸 Screenshots/Examples
🔄 Breaking changes
Values without reserved characters are unchanged (no quoting added). The escaping only applies when a value already triggers the existing quoting path.
📋 Checklist
fix(postgrest): ...pnpm nx formatto ensure consistent code formatting📝 Additional notes
Validated E2E against a real PostgREST server (Supabase CLI local, port 54321): the test suite inserts rows whose usernames contain reserved chars and double quotes, then filters by them — confirming the escaping survives the full pipeline (URL → PostgREST parser → PostgreSQL). 8/8 tests pass.
Local checks:
jest test/filter-encoding.test.ts→ 8 passed,tsc --noEmit→ clean,prettier --check→ clean.The initial attempt used CSV-style
""doubling (inspired by PostgREST v7 docs); E2E testing against the real server caught this — PostgREST expects backslash escaping\"/\\, confirmed by the current docs and by directcurltests.