From ac66323394025f577328c6eb86eeb5396d9fd086 Mon Sep 17 00:00:00 2001 From: Christopher League Date: Tue, 13 Aug 2019 10:04:10 -0400 Subject: [PATCH 1/5] yesod-test: failing tests for encoding errors Related to issue #1616 --- yesod-test/test/main.hs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/yesod-test/test/main.hs b/yesod-test/test/main.hs index c488d7ee..5bd45a17 100644 --- a/yesod-test/test/main.hs +++ b/yesod-test/test/main.hs @@ -145,9 +145,11 @@ main = hspec $ do request $ do setMethod "POST" setUrl $ LiteAppRoute ["post"] - addPostParam "foo" "foobarbaz" + -- If value uses special characters, + addPostParam "foo" "foo+bar%41&baz" statusIs 200 - bodyEquals "foobarbaz" + -- They pass through the server correctly. + bodyEquals "foo+bar%41&baz" yit "labels" $ do get ("/form" :: Text) statusIs 200 @@ -155,11 +157,13 @@ main = hspec $ do request $ do setMethod "POST" setUrl ("/form" :: Text) - byLabel "Some Label" "12345" + byLabel "Some Label" "foo+bar%41&baz" fileByLabel "Some File" "test/main.hs" "text/plain" addToken statusIs 200 - bodyEquals "12345" + -- The '%', '&' get further encoded because "/form" + -- (unlike "/post") uses toHtml. + bodyEquals "foo+bar%2541&baz" yit "labels WForm" $ do get ("/wform" :: Text) statusIs 200 From a79f73a040d769d287e1aec17c54f910d55ffb13 Mon Sep 17 00:00:00 2001 From: Christopher League Date: Tue, 13 Aug 2019 10:34:57 -0400 Subject: [PATCH 2/5] yesod-test: url-encode addPostParam keys & values Fixes #1616 --- yesod-test/Yesod/Test.hs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/yesod-test/Yesod/Test.hs b/yesod-test/Yesod/Test.hs index 9f886b76..ef5af224 100644 --- a/yesod-test/Yesod/Test.hs +++ b/yesod-test/Yesod/Test.hs @@ -1242,8 +1242,9 @@ request reqBuilder = do BS8.concat $ separator : [BS8.concat [multipartPart p, separator] | p <- parts] multipartPart (ReqKvPart k v) = BS8.concat [ "Content-Disposition: form-data; " - , "name=\"", TE.encodeUtf8 k, "\"\r\n\r\n" - , TE.encodeUtf8 v, "\r\n"] + , "name=\"", enc k, "\"\r\n\r\n" + , enc v, "\r\n"] + where enc = H.urlEncode False . TE.encodeUtf8 multipartPart (ReqFilePart k v bytes mime) = BS8.concat [ "Content-Disposition: form-data; " , "name=\"", TE.encodeUtf8 k, "\"; " @@ -1266,14 +1267,14 @@ request reqBuilder = do ([ ("Cookie", cookieValue) ] ++ headersForPostData rbdPostData) method extraHeaders urlPath urlQuery) simpleRequestBody' (MultipleItemsPostData x) = - BSL8.fromChunks $ return $ TE.encodeUtf8 $ T.intercalate "&" - $ map singlepartPart x + BSL8.fromChunks $ return $ H.renderSimpleQuery False + $ concatMap singlepartPart x simpleRequestBody' (BinaryPostData x) = x cookieValue = Builder.toByteString $ Cookie.renderCookies cookiePairs cookiePairs = [ (Cookie.setCookieName c, Cookie.setCookieValue c) | c <- map snd $ M.toList cookies ] - singlepartPart (ReqFilePart _ _ _ _) = "" - singlepartPart (ReqKvPart k v) = T.concat [k,"=",v] + singlepartPart (ReqFilePart _ _ _ _) = [] + singlepartPart (ReqKvPart k v) = [(TE.encodeUtf8 k, TE.encodeUtf8 v)] -- If the request appears to be submitting a form (has key-value pairs) give it the form-urlencoded Content-Type. -- The previous behavior was to always use the form-urlencoded Content-Type https://github.com/yesodweb/yesod/issues/1063 From 3f98190645d5a51434597015c841027097e61e8e Mon Sep 17 00:00:00 2001 From: Christopher League Date: Tue, 13 Aug 2019 10:39:44 -0400 Subject: [PATCH 3/5] Bump version to 1.6.6.2 --- yesod-test/yesod-test.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yesod-test/yesod-test.cabal b/yesod-test/yesod-test.cabal index b71acd06..c712e2b2 100644 --- a/yesod-test/yesod-test.cabal +++ b/yesod-test/yesod-test.cabal @@ -1,5 +1,5 @@ name: yesod-test -version: 1.6.6.1 +version: 1.6.6.2 license: MIT license-file: LICENSE author: Nubis From 08a9632ebaf385be432867fbed713cbd9c7e6148 Mon Sep 17 00:00:00 2001 From: Christopher League Date: Tue, 13 Aug 2019 11:58:11 -0400 Subject: [PATCH 4/5] yesod-test: correction to PR for multipart --- yesod-test/Yesod/Test.hs | 5 ++--- yesod-test/test/main.hs | 12 ++++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/yesod-test/Yesod/Test.hs b/yesod-test/Yesod/Test.hs index ef5af224..79640a32 100644 --- a/yesod-test/Yesod/Test.hs +++ b/yesod-test/Yesod/Test.hs @@ -1242,9 +1242,8 @@ request reqBuilder = do BS8.concat $ separator : [BS8.concat [multipartPart p, separator] | p <- parts] multipartPart (ReqKvPart k v) = BS8.concat [ "Content-Disposition: form-data; " - , "name=\"", enc k, "\"\r\n\r\n" - , enc v, "\r\n"] - where enc = H.urlEncode False . TE.encodeUtf8 + , "name=\"", TE.encodeUtf8 k, "\"\r\n\r\n" + , TE.encodeUtf8 v, "\r\n"] multipartPart (ReqFilePart k v bytes mime) = BS8.concat [ "Content-Disposition: form-data; " , "name=\"", TE.encodeUtf8 k, "\"; " diff --git a/yesod-test/test/main.hs b/yesod-test/test/main.hs index 5bd45a17..77957d9c 100644 --- a/yesod-test/test/main.hs +++ b/yesod-test/test/main.hs @@ -146,10 +146,10 @@ main = hspec $ do setMethod "POST" setUrl $ LiteAppRoute ["post"] -- If value uses special characters, - addPostParam "foo" "foo+bar%41&baz" + addPostParam "foo" "foo+bar%41<&baz" statusIs 200 -- They pass through the server correctly. - bodyEquals "foo+bar%41&baz" + bodyEquals "foo+bar%41<&baz" yit "labels" $ do get ("/form" :: Text) statusIs 200 @@ -157,13 +157,13 @@ main = hspec $ do request $ do setMethod "POST" setUrl ("/form" :: Text) - byLabel "Some Label" "foo+bar%41&baz" + byLabel "Some Label" "foo+bar%41<&baz" fileByLabel "Some File" "test/main.hs" "text/plain" addToken statusIs 200 - -- The '%', '&' get further encoded because "/form" - -- (unlike "/post") uses toHtml. - bodyEquals "foo+bar%2541&baz" + -- The '<' and '&' get encoded to HTML entities because + -- "/form" (unlike "/post") uses toHtml. + bodyEquals "foo+bar%41<&baz" yit "labels WForm" $ do get ("/wform" :: Text) statusIs 200 From fa90ab19ca20da2e2f9bd795731ad98a578c5841 Mon Sep 17 00:00:00 2001 From: Christopher League Date: Mon, 19 Aug 2019 15:57:15 -0400 Subject: [PATCH 5/5] Update changelog --- yesod-test/ChangeLog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/yesod-test/ChangeLog.md b/yesod-test/ChangeLog.md index 0b9e7c34..2b991735 100644 --- a/yesod-test/ChangeLog.md +++ b/yesod-test/ChangeLog.md @@ -1,5 +1,11 @@ # ChangeLog for yesod-test +## 1.6.6.2 + +addPostParam will now URL-encode keys and values to prevent corruption +when special characters such as `&` are used +[#1617](https://github.com/yesodweb/yesod/pull/1617) + ## 1.6.6.1 * Documentation fixes