Skip to content
This repository was archived by the owner on Oct 19, 2024. It is now read-only.

Commit 6090317

Browse files
author
Flavio Corpa
authored
📦💥 Defend against possible explosion of decodeUtf8 (#250)
1 parent f61e898 commit 6090317

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

graphql/src/Mu/GraphQL/Server.hs

+25-15
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ module Mu.GraphQL.Server (
3636

3737
import Control.Applicative ((<|>))
3838
import Control.Exception (throw)
39-
import Control.Monad.Except
39+
import Control.Monad.Except (MonadIO (..), join, runExceptT)
4040
import qualified Data.Aeson as A
4141
import Data.Aeson.Text (encodeToLazyText)
4242
import Data.ByteString.Lazy (fromStrict, toStrict)
43-
import Data.Conduit
43+
import Data.Conduit (ConduitT, transPipe)
4444
import qualified Data.HashMap.Strict as HM
45-
import Data.Proxy
45+
import Data.Proxy (Proxy (..))
4646
import qualified Data.Text as T
47-
import Data.Text.Encoding (decodeUtf8)
47+
import Data.Text.Encoding (decodeUtf8')
4848
import qualified Data.Text.Lazy.Encoding as T
4949
import Language.GraphQL.Draft.Parser (parseExecutableDoc)
5050
import qualified Language.GraphQL.Draft.Syntax as GQL
@@ -57,8 +57,9 @@ import Network.Wai.Handler.Warp (Port, Settings, run, runSetti
5757
import qualified Network.Wai.Handler.WebSockets as WS
5858
import qualified Network.WebSockets as WS
5959

60-
import Mu.GraphQL.Query.Parse
61-
import Mu.GraphQL.Query.Run
60+
import Data.Text.Encoding.Error (UnicodeException (..))
61+
import Mu.GraphQL.Query.Parse (VariableMapC)
62+
import Mu.GraphQL.Query.Run (GraphQLApp, runPipeline, runSubscriptionPipeline)
6263
import Mu.GraphQL.Subscription.Protocol
6364
import Mu.Server
6465

@@ -133,17 +134,22 @@ httpGraphQLAppTrans ::
133134
-> Application
134135
httpGraphQLAppTrans f server q m s req res =
135136
case parseMethod (requestMethod req) of
136-
Left err -> toError $ decodeUtf8 err
137-
Right GET -> do
137+
Left err -> toError $ either unpackUnicodeException id (decodeUtf8' err)
138+
Right GET -> do
138139
let qst = queryString req
139-
opN = decodeUtf8 <$> join (lookup "operationName" qst)
140-
case (fmap decodeUtf8 <$> lookup "query" qst, lookup "variables" qst) of
141-
(Just (Just qry), Just (Just vars)) ->
140+
opN = decodeUtf8' <$> join (lookup "operationName" qst)
141+
decodedQuery = fmap decodeUtf8' =<< lookup "query" qst
142+
case (decodedQuery, lookup "variables" qst) of
143+
(Just (Right qry), Just (Just vars)) ->
142144
case A.eitherDecode $ fromStrict vars of
143145
Left err -> toError $ T.pack err
144-
Right vrs -> execQuery opN vrs qry
145-
(Just (Just qry), _) -> execQuery opN HM.empty qry
146-
_ -> toError "Error parsing query"
146+
Right vrs -> case sequence opN of
147+
Left err -> toError $ "Could not parse operation name: " <> unpackUnicodeException err
148+
Right opName -> execQuery opName vrs qry
149+
(Just (Right qry), _) -> case sequence opN of
150+
Left err -> toError $ "Could not parse query: " <> unpackUnicodeException err
151+
Right opName -> execQuery opName HM.empty qry
152+
_ -> toError "Error parsing query"
147153
Right POST -> do
148154
body <- strictRequestBody req
149155
case lookup hContentType $ requestHeaders req of
@@ -152,7 +158,9 @@ httpGraphQLAppTrans f server q m s req res =
152158
Left err -> toError $ T.pack err
153159
Right (GraphQLInput qry vars opName) -> execQuery opName vars qry
154160
Just "application/graphql" ->
155-
execQuery Nothing HM.empty (decodeUtf8 $ toStrict body)
161+
case decodeUtf8' $ toStrict body of
162+
Left err -> toError $ "Could not decode utf8 from body: " <> unpackUnicodeException err
163+
Right msg -> execQuery Nothing HM.empty msg
156164
_ -> toError "No `Content-Type` header found!"
157165
_ -> toError "Unsupported method"
158166
where
@@ -166,6 +174,8 @@ httpGraphQLAppTrans f server q m s req res =
166174
toError err = toResponse $ A.object [ ("errors", A.Array [ A.object [ ("message", A.String err) ] ])]
167175
toResponse :: A.Value -> IO ResponseReceived
168176
toResponse = res . responseBuilder ok200 [] . T.encodeUtf8Builder . encodeToLazyText
177+
unpackUnicodeException :: UnicodeException -> T.Text
178+
unpackUnicodeException (DecodeError str _) = T.pack str
169179

170180
wsGraphQLAppTrans
171181
:: ( GraphQLApp p qr mut sub m chn hs )

0 commit comments

Comments
 (0)