diff --git a/CHANGELOG.md b/CHANGELOG.md index 304b59a0f8..e5ae0ed800 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). + Enables calling a function with a single json parameter without using `Prefer: params=single-object` + Enables uploading bytea to a function with `Content-Type: application/octet-stream` + Enables uploading raw text to a function with `Content-Type: text/plain` +- #1938, Allow escaping inside double quotes with a backslash, e.g. `?col=in.("Double\"Quote")`, `?col=in.("Back\\slash")` - @steve-chavez ### Fixed diff --git a/src/PostgREST/Request/Parsers.hs b/src/PostgREST/Request/Parsers.hs index 0c4cbb9792..a73ea2690d 100644 --- a/src/PostgREST/Request/Parsers.hs +++ b/src/PostgREST/Request/Parsers.hs @@ -207,7 +207,9 @@ pListElement :: Parser Text pListElement = try (pQuotedValue <* notFollowedBy (noneOf ",)")) <|> (toS <$> many (noneOf ",)")) pQuotedValue :: Parser Text -pQuotedValue = toS <$> (char '"' *> many (noneOf "\"") <* char '"') +pQuotedValue = toS <$> (char '"' *> many pCharsOrSlashed <* char '"') + where + pCharsOrSlashed = noneOf "\\\"" <|> (char '\\' *> anyChar) pDelimiter :: Parser Char pDelimiter = char '.' "delimiter (.)" diff --git a/test/Feature/QuerySpec.hs b/test/Feature/QuerySpec.hs index 350216dc41..33b6783061 100644 --- a/test/Feature/QuerySpec.hs +++ b/test/Feature/QuerySpec.hs @@ -953,6 +953,25 @@ spec actualPgVersion = do [json| [{"name":"Double O Seven(007)"}] |] { matchHeaders = [matchContentTypeJson] } + context "escaped chars" $ do + it "accepts escaped double quotes" $ + get "/w_or_wo_comma_names?name=in.(\"Double\\\"Quote\\\"McGraw\\\"\")" `shouldRespondWith` + [json| [ { "name": "Double\"Quote\"McGraw\"" } ] |] + { matchHeaders = [matchContentTypeJson] } + + it "accepts escaped backslashes" $ do + get "/w_or_wo_comma_names?name=in.(\"\\\\\")" `shouldRespondWith` + [json| [{ "name": "\\" }] |] + { matchHeaders = [matchContentTypeJson] } + get "/w_or_wo_comma_names?name=in.(\"/\\\\Slash/\\\\Beast/\\\\\")" `shouldRespondWith` + [json| [ { "name": "/\\Slash/\\Beast/\\" } ] |] + { matchHeaders = [matchContentTypeJson] } + + it "passes any escaped char as the same char" $ + get "/w_or_wo_comma_names?name=in.(\"D\\a\\vid W\\h\\ite\")" `shouldRespondWith` + [json| [{ "name": "David White" }] |] + { matchHeaders = [matchContentTypeJson] } + describe "IN values without quotes" $ do it "accepts single double quotes as values" $ do get "/w_or_wo_comma_names?name=in.(\")" `shouldRespondWith`