fix: regression with parameter charset=utf-8 in mediatype

This commit is contained in:
Taimoor Zaeem
2025-04-21 17:06:26 -05:00
committed by Steve Chavez
parent a7f9181462
commit 38c596800a
3 changed files with 29 additions and 4 deletions
+4
View File
@@ -5,6 +5,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## Unreleased ## Unreleased
### Fixed
- #4030, Fix regression with parameter `charset=utf-8` in mediatype - @taimoorzaeem
## [12.2.10] - 2025-04-18 ## [12.2.10] - 2025-04-18
### Fixed ### Fixed
+4 -4
View File
@@ -183,14 +183,14 @@ decodeMediaType mt = decodeMediaType' $ decodeLatin1 mt
-- >>> P.parse tokenizeMediaType "" "application/vnd.pgrst.plan+text; for=\"text/xml\"; options=analyze|verbose|settings|buffers|wal" -- >>> P.parse tokenizeMediaType "" "application/vnd.pgrst.plan+text; for=\"text/xml\"; options=analyze|verbose|settings|buffers|wal"
-- Right ("application","vnd.pgrst.plan+text",[("for","text/xml"),("options","analyze|verbose|settings|buffers|wal")]) -- Right ("application","vnd.pgrst.plan+text",[("for","text/xml"),("options","analyze|verbose|settings|buffers|wal")])
-- TODO: Improve mediatype parser as per RFC 2045 https://datatracker.ietf.org/doc/html/rfc2045#section-5.1
tokenizeMediaType :: P.Parser (Text, Text, [(Text, Text)]) tokenizeMediaType :: P.Parser (Text, Text, [(Text, Text)])
tokenizeMediaType = do tokenizeMediaType = do
mainType <- P.many1 (P.alphaNum <|> P.oneOf ".*") mainType <- P.many1 (P.alphaNum <|> P.oneOf ".*")
P.char '/' P.char '/'
subType <- P.many1 (P.alphaNum <|> P.oneOf ".*+-") subType <- P.many1 (P.alphaNum <|> P.oneOf ".*+-")
params <- P.many pSemicolonSeparatedKeyVals params <- P.many pSemicolonSeparatedKeyVals
P.optional $ P.try $ P.spaces *> P.char ';' -- ending semicolon P.optional $ P.try $ P.spaces *> P.char ';' -- ending semicolon, discard input after that because it has already failed or we have hit EOF
P.eof
return (T.pack mainType, T.pack subType, params) return (T.pack mainType, T.pack subType, params)
where where
pSemicolonSeparatedKeyVals :: P.Parser (Text, Text) pSemicolonSeparatedKeyVals :: P.Parser (Text, Text)
@@ -198,12 +198,12 @@ tokenizeMediaType = do
where where
pKeyVal :: P.Parser (Text, Text) pKeyVal :: P.Parser (Text, Text)
pKeyVal = do pKeyVal = do
key <- P.many1 P.alphaNum key <- P.many1 (P.alphaNum <|> P.oneOf "-")
P.spaces P.spaces
P.char '=' P.char '='
P.spaces P.spaces
val <- P.try pQuoted <|> P.try pUnQuoted val <- P.try pQuoted <|> P.try pUnQuoted
return (T.pack key, T.pack val) return (T.pack key, T.pack val)
where where
pUnQuoted = P.many1 (P.alphaNum <|> P.oneOf "|") pUnQuoted = P.many1 (P.alphaNum <|> P.oneOf "|-")
pQuoted = P.char '\"' *> P.manyTill P.anyChar (P.char '\"') pQuoted = P.char '\"' *> P.manyTill P.anyChar (P.char '\"')
@@ -382,3 +382,24 @@ spec = describe "custom media types" $ do
`shouldRespondWith` `shouldRespondWith`
[json| {"code":"PGRST107","details":null,"hint":null,"message":"None of these media types are available: undefined"} |] [json| {"code":"PGRST107","details":null,"hint":null,"message":"None of these media types are available: undefined"} |]
{ matchStatus = 406 } { matchStatus = 406 }
context "media type parser allowed characters" $ do
it "regression test allowing charset=utf-8" $
request methodPost "/rpc/overloaded_default"
[("Content-Type", "application/json; charset=utf-8")]
[json|{"must_param":1}|]
`shouldRespondWith`
[json|{"val":1}|]
{ matchStatus = 200
, matchHeaders = ["Content-Type" <:> "application/json; charset=utf-8"]
}
it "handle unrecognized parameters leniently" $ do
request methodPost "/rpc/overloaded_default"
[("Content-Type", "application/json; $$ unrecognized-chars=ignored $$")]
[json|{"must_param":1}|]
`shouldRespondWith`
[json|{"val":1}|]
{ matchStatus = 200
, matchHeaders = ["Content-Type" <:> "application/json; charset=utf-8"]
}