Escape special characters in the encoded strings

Fixes #2.
This commit is contained in:
Eugen Wissner 2019-08-13 07:24:05 +02:00
parent 6604fba7f4
commit 045b6d15fb
4 changed files with 50 additions and 22 deletions

View File

@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file.
### Added ### Added
- `executeWithName` executes an operation with the given name. - `executeWithName` executes an operation with the given name.
- Export `Language.GraphQL.Encoder.definition`. - Export `Language.GraphQL.Encoder.definition`.
- Export `Language.GraphQL.Encoder.value`. Escapes \ and " in strings now.
- Export `Language.GraphQL.Encoder.type'`.
### Changed ### Changed
- `Operation` includes now possible operation name which allows to support - `Operation` includes now possible operation name which allows to support

View File

@ -4,7 +4,7 @@ cabal-version: 1.12
-- --
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
-- --
-- hash: dca80d6bcaa432cabc2499efc9f047c6f59546bc2ba75b35fed6efd694895598 -- hash: cb68243309f47fc44768d14981c4f6f8b3f1bb9dc37dd17a63996418d6aac375
name: graphql name: graphql
version: 0.4.0.0 version: 0.4.0.0
@ -66,6 +66,7 @@ test-suite tasty
type: exitcode-stdio-1.0 type: exitcode-stdio-1.0
main-is: Spec.hs main-is: Spec.hs
other-modules: other-modules:
Language.GraphQL.EncoderSpec
Language.GraphQL.ErrorSpec Language.GraphQL.ErrorSpec
Language.GraphQL.LexerSpec Language.GraphQL.LexerSpec
Language.GraphQL.ParserSpec Language.GraphQL.ParserSpec

View File

@ -8,6 +8,8 @@ module Language.GraphQL.Encoder
, document , document
, minified , minified
, pretty , pretty
, type'
, value
) where ) where
import Data.Foldable (fold) import Data.Foldable (fold)
@ -84,7 +86,7 @@ variableDefinition :: Formatter -> VariableDefinition -> Text
variableDefinition formatter (VariableDefinition var ty dv) variableDefinition formatter (VariableDefinition var ty dv)
= variable var = variable var
<> eitherFormat formatter ": " ":" <> eitherFormat formatter ": " ":"
<> type_ ty <> type' ty
<> maybe mempty (defaultValue formatter) dv <> maybe mempty (defaultValue formatter) dv
defaultValue :: Formatter -> Value -> Text defaultValue :: Formatter -> Value -> Text
@ -160,8 +162,19 @@ fragmentDefinition formatter (FragmentDefinition name tc dirs sels)
<> eitherFormat formatter " " mempty <> eitherFormat formatter " " mempty
<> selectionSet formatter sels <> selectionSet formatter sels
-- * Values -- * Directives
directives :: Formatter -> Directives -> Text
directives formatter@(Pretty _) = Text.Lazy.cons ' ' . spaces (directive formatter)
directives Minified = spaces (directive Minified)
directive :: Formatter -> Directive -> Text
directive formatter (Directive name args)
= "@" <> Text.Lazy.fromStrict name <> optempty (arguments formatter) args
-- * Miscellaneous
-- | Converts a 'Value' into a string.
value :: Formatter -> Value -> Text value :: Formatter -> Value -> Text
value _ (ValueVariable x) = variable x value _ (ValueVariable x) = variable x
value _ (ValueInt x) = toLazyText $ decimal x value _ (ValueInt x) = toLazyText $ decimal x
@ -177,9 +190,11 @@ booleanValue :: Bool -> Text
booleanValue True = "true" booleanValue True = "true"
booleanValue False = "false" booleanValue False = "false"
-- TODO: Escape characters
stringValue :: Text -> Text stringValue :: Text -> Text
stringValue = quotes stringValue
= quotes
. Text.Lazy.replace "\"" "\\\""
. Text.Lazy.replace "\\" "\\\\"
listValue :: Formatter -> [Value] -> Text listValue :: Formatter -> [Value] -> Text
listValue formatter = bracketsCommas formatter $ value formatter listValue formatter = bracketsCommas formatter $ value formatter
@ -201,25 +216,14 @@ objectField formatter (ObjectField name v)
| Pretty _ <- formatter = ": " | Pretty _ <- formatter = ": "
| Minified <- formatter = ":" | Minified <- formatter = ":"
-- * Directives -- | Converts a 'Type' a type into a string.
type' :: Type -> Text
directives :: Formatter -> [Directive] -> Text type' (TypeNamed x) = Text.Lazy.fromStrict x
directives formatter@(Pretty _) = Text.Lazy.cons ' ' . spaces (directive formatter) type' (TypeList x) = listType x
directives Minified = spaces (directive Minified) type' (TypeNonNull x) = nonNullType x
directive :: Formatter -> Directive -> Text
directive formatter (Directive name args)
= "@" <> Text.Lazy.fromStrict name <> optempty (arguments formatter) args
-- * Type Reference
type_ :: Type -> Text
type_ (TypeNamed x) = Text.Lazy.fromStrict x
type_ (TypeList x) = listType x
type_ (TypeNonNull x) = nonNullType x
listType :: Type -> Text listType :: Type -> Text
listType x = brackets (type_ x) listType x = brackets (type' x)
nonNullType :: NonNullType -> Text nonNullType :: NonNullType -> Text
nonNullType (NonNullTypeNamed x) = Text.Lazy.fromStrict x <> "!" nonNullType (NonNullTypeNamed x) = Text.Lazy.fromStrict x <> "!"

View File

@ -0,0 +1,21 @@
{-# LANGUAGE OverloadedStrings #-}
module Language.GraphQL.EncoderSpec
( spec
) where
import Language.GraphQL.AST ( Value(..))
import Language.GraphQL.Encoder ( value
, minified
)
import Test.Hspec ( Spec
, describe
, it
, shouldBe
)
spec :: Spec
spec = describe "value" $ do
it "escapes \\" $
value minified (ValueString "\\") `shouldBe` "\"\\\\\""
it "escapes quotes" $
value minified (ValueString "\"") `shouldBe` "\"\\\"\""