fix(postgrest): escape embedded quotes and backslashes in in()/notIn() filter values - #2489
fix(postgrest): escape embedded quotes and backslashes in in()/notIn() filter values#2489kazuki-netizen wants to merge 1 commit into
Conversation
…) filter values Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mandarini
left a comment
There was a problem hiding this comment.
Hi @kazuki-netizen, thank you so much for contributing to Supabase! 💚
This is a real bug and a clean fix. One thing before this can merge: test/in-filter-escaping.test.ts mocks fetch, so it only checks that the code agrees with itself about the expected string, it never proves the value survives a real PostgREST server. This package already has a Docker-backed PostgREST instance for exactly this (nx test:infra postgrest-js), and the existing tests in test/filters.test.ts hit it directly at localhost:54321. Could you add one test there that inserts a row with a tricky value (something like a"b,c) and asserts .in() / .notIn() return it correctly? That gives the fix durable proof against the real server contract instead of just the mock, and it should be a small addition alongside what you already have.
Thank you again for digging into this one, it's contributions like yours that keep these SDKs solid.
What
.in()and.notIn()wrap values containing PostgREST reserved characters (,()) in double quotes, but do not escape a"or\inside the value. A value likea"b,ccurrently serializes toin.("a"b,c"), whose stray quote breaks PostgREST's list parsing.Fix
Escape
\→\\and"→\"(backslash first) before wrapping. This matches PostgREST's quoted-element parser (pQuotedValueinApiRequest/QueryParams.hs, where a backslash escapes the following character inside quotes; see also PostgREST/postgrest#1938 and supabase/postgrest-js#164). The shared logic is extracted into a smallformatInFilterValue()helper used by bothin()andnotIn(). Simple values are still emitted unquoted — no behavior change for existing callers.Test
Adds
test/in-filter-escaping.test.tswith URL-level assertions (mock fetch, no live server) covering reserved-char quoting, embedded-quote escaping, backslash escaping, simple-value passthrough, andnotInparity. All 6 pass;tsc --noEmit, ESLint, and Prettier are clean on the touched files.🤖 Generated with Claude Code