on develop help sign in
Merge pull request #58 from brendanhay/feature/base64-invalid-encoding

Invalid Base64 De/serialisation

commite5b42bbdc7826406e811c06e54282401a27d8fae authorBrendan Hay <brendanhay@users.noreply.github.com> dateSat 11 Feb 2017, 11:20 (10 years ago) parent1b8050830a6050
13 files changed+78−88
core/gogol-core.cabal+1−2 core/src/Network/Google/Data/Base64.hs−53 core/src/Network/Google/Data/Bytes.hs+49 core/src/Network/Google/Prelude.hs+1−1 gen/.ghci+3 gen/gogol-gen.cabal+3−3 gen/src/Gen/Orphans.hs−11 gen/src/Gen/Syntax.hs+2−2 gen/src/Gen/Types/Data.hs−1 gen/src/Gen/Types/Id.hs+15−13 gen/src/Gen/Types/Schema.hs−1 gen/src/Main.hs+2−1 gen/stack.yaml+2
core/gogol-core.cabal+1−2
@@ -36,7 +36,7 @@ library
3636 ghc-options: -Wall
3737
3838 exposed-modules:
39− Network.Google.Data.Base64
39+ Network.Google.Data.Bytes
4040 , Network.Google.Data.JSON
4141 , Network.Google.Data.Numeric
4242 , Network.Google.Data.Time
@@ -59,7 +59,6 @@ library
5959 , http-media >= 0.6
6060 , http-types >= 0.8.6
6161 , lens >= 4.4
62− , memory >= 0.8
6362 , resourcet >= 1.1
6463 , scientific >= 0.3
6564 , servant >= 0.4.4
core/src/Network/Google/Data/Base64.hsdeleted−53
@@ -1,53 +0,0 @@
1−{-# LANGUAGE DeriveDataTypeable #-}
2−{-# LANGUAGE DeriveGeneric #-}
3−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4−
5−-- |
6−-- Module : Network.Google.Data.Base64
7−-- Copyright : (c) 2013-2016 Brendan Hay
8−-- License : Mozilla Public License, v. 2.0.
9−-- Maintainer : Brendan Hay <brendan.g.hay@gmail.com>
10−-- Stability : provisional
11−-- Portability : non-portable (GHC extensions)
12−--
13−module Network.Google.Data.Base64
14− ( Base64 (..)
15− , _Base64
16− ) where
17−
18−import Control.Lens (Iso', iso)
19−import Data.Aeson (FromJSON (..), ToJSON (..))
20−import qualified Data.ByteArray.Encoding as BA
21−import Data.ByteString (ByteString)
22−import qualified Data.ByteString.Char8 as BS8
23−import Data.Data (Data, Typeable)
24−import Data.Hashable
25−import qualified Data.Text.Encoding as Text
26−import GHC.Generics (Generic)
27−import Network.Google.Data.JSON (parseJSONText, toJSONText)
28−import Web.HttpApiData (FromHttpApiData (..),
29− ToHttpApiData (..))
30−
31−-- | Base64 encoded binary data.
32−--
33−-- Encoding\/decoding is automatically deferred to serialisation and deserialisation
34−-- respectively.
35−newtype Base64 = Base64 { unBase64 :: ByteString }
36− deriving (Eq, Read, Ord, Data, Typeable, Generic)
37−
38−instance Hashable Base64
39−
40−_Base64 :: Iso' Base64 ByteString
41−_Base64 = iso unBase64 Base64
42−
43−instance ToHttpApiData Base64 where
44− toQueryParam = Text.decodeUtf8 . toHeader
45− toHeader = BA.convertToBase BA.Base64 . unBase64
46−
47−instance FromHttpApiData Base64 where
48− parseQueryParam = parseHeader . Text.encodeUtf8
49− parseHeader = either fail (pure . Base64) . BA.convertFromBase BA.Base64
50−
51−instance Show Base64 where show = show . BS8.unpack . unBase64
52−instance FromJSON Base64 where parseJSON = parseJSONText "Base64"
53−instance ToJSON Base64 where toJSON = toJSONText
core/src/Network/Google/Data/Bytes.hsnew file+49
@@ -0,0 +1,49 @@
1+{-# LANGUAGE DeriveDataTypeable #-}
2+{-# LANGUAGE DeriveGeneric #-}
3+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4+
5+-- |
6+-- Module : Network.Google.Data.Bytes
7+-- Copyright : (c) 2013-2016 Brendan Hay
8+-- License : Mozilla Public License, v. 2.0.
9+-- Maintainer : Brendan Hay <brendan.g.hay@gmail.com>
10+-- Stability : provisional
11+-- Portability : non-portable (GHC extensions)
12+--
13+module Network.Google.Data.Bytes
14+ ( Bytes (..)
15+ , _Bytes
16+ ) where
17+
18+import Control.Lens (Iso', iso)
19+import Data.Aeson (FromJSON (..), ToJSON (..))
20+import Data.ByteString (ByteString)
21+import Data.Data (Data, Typeable)
22+import Data.Hashable
23+import qualified Data.Text.Encoding as Text
24+import GHC.Generics (Generic)
25+import Network.Google.Data.JSON (parseJSONText, toJSONText)
26+import Web.HttpApiData (FromHttpApiData (..),
27+ ToHttpApiData (..))
28+-- | Binary data.
29+--
30+-- This data is passed to/from the serialisation routines as-is, and any
31+-- particular encoding or decoding (say, base64) is left up to the caller.
32+newtype Bytes = Bytes { unBytes :: ByteString }
33+ deriving (Eq, Show, Read, Ord, Data, Typeable, Generic)
34+
35+instance Hashable Bytes
36+
37+_Bytes :: Iso' Bytes ByteString
38+_Bytes = iso unBytes Bytes
39+
40+instance ToHttpApiData Bytes where
41+ toQueryParam = Text.decodeUtf8 . unBytes
42+ toHeader = unBytes
43+
44+instance FromHttpApiData Bytes where
45+ parseQueryParam = pure . Bytes . Text.encodeUtf8
46+ parseHeader = pure . Bytes
47+
48+instance FromJSON Bytes where parseJSON = parseJSONText "Bytes"
49+instance ToJSON Bytes where toJSON = toJSONText
core/src/Network/Google/Prelude.hs+1−1
@@ -31,7 +31,7 @@ import Servant.API as Export hiding (Headers, getResponse)
3131import Servant.Utils.Links as Export hiding (Link)
3232import Web.HttpApiData as Export (FromHttpApiData (..), ToHttpApiData (..))
3333
34−import Network.Google.Data.Base64 as Export
34+import Network.Google.Data.Bytes as Export
3535import Network.Google.Data.JSON as Export
3636import Network.Google.Data.Numeric as Export
3737import Network.Google.Data.Time as Export
gen/.ghcinew file+3
@@ -0,0 +1,3 @@
1+:set -XOverloadedStrings
2+
3+:set prompt "> "
gen/gogol-gen.cabal+3−3
@@ -44,7 +44,7 @@ executable gogol-gen
4444 ghc-options: -Wall -threaded
4545
4646 build-depends:
47− aeson
47+ aeson >= 1
4848 , attoparsec
4949 , base >= 4.8
5050 , bifunctors
@@ -55,8 +55,8 @@ executable gogol-gen
5555 , errors >= 2.1.2
5656 , formatting
5757 , hashable
58− , haskell-src-exts >= 1.17.1
59− , hindent
58+ , haskell-src-exts == 1.17.1
59+ , hindent < 5
6060 , lens
6161 , mtl
6262 , optparse-applicative
gen/src/Gen/Orphans.hs−11
@@ -11,14 +11,9 @@
1111
1212module Gen.Orphans where
1313
14−import Data.Aeson
15−import Data.Bifunctor
1614import Data.Hashable
17−import qualified Data.HashMap.Strict as Map
1815import Data.String
19−import qualified Data.Text as Text
2016import Language.Haskell.Exts.Build
21−import Language.Haskell.Exts.Pretty
2217import Language.Haskell.Exts.Syntax
2318
2419instance Hashable Name
@@ -26,9 +21,3 @@ instance Hashable Name
2621instance IsString Name where fromString = name
2722instance IsString QName where fromString = UnQual . name
2823instance IsString QOp where fromString = op . sym
29−
30−instance ToJSON a => ToJSON (Map.HashMap Name a) where
31− toJSON = toJSON
32− . Map.fromList
33− . map (first (Text.pack . prettyPrint))
34− . Map.toList
gen/src/Gen/Syntax.hs+2−2
@@ -588,7 +588,7 @@ internalLit = \case
588588 Nat -> TyApp (TyCon "Textual") (TyCon "Nat")
589589 Float -> TyApp (TyCon "Textual") (TyCon "Double")
590590 Double -> TyApp (TyCon "Textual") (TyCon "Double")
591− Byte -> TyCon "Base64"
591+ Byte -> TyCon "Bytes"
592592 UInt32 -> TyApp (TyCon "Textual") (TyCon "Word32")
593593 UInt64 -> TyApp (TyCon "Textual") (TyCon "Word64")
594594 Int32 -> TyApp (TyCon "Textual") (TyCon "Int32")
@@ -622,7 +622,7 @@ iso = \case
622622 TLit Duration -> Just (var "_Duration")
623623 TLit Float -> Just (var "_Coerce")
624624 TLit Double -> Just (var "_Coerce")
625− TLit Byte -> Just (var "_Base64")
625+ TLit Byte -> Just (var "_Bytes")
626626 TLit UInt32 -> Just (var "_Coerce")
627627 TLit UInt64 -> Just (var "_Coerce")
628628 TLit Int32 -> Just (var "_Coerce")
gen/src/Gen/Types/Data.hs−1
@@ -31,7 +31,6 @@ import Data.Text (Text)
3131import qualified Data.Text as Text
3232import qualified Data.Text.Lazy as LText
3333import Data.Text.Manipulate
34−import Gen.Orphans ()
3534import Gen.Types.Help
3635import Gen.Types.Id
3736import Gen.Types.NS
gen/src/Gen/Types/Id.hs+15−13
@@ -58,12 +58,10 @@ import Control.Applicative
5858import Control.Monad
5959import Data.Aeson hiding (Bool, String)
6060import qualified Data.Attoparsec.Text as A
61−import Data.Bifunctor (first)
6261import qualified Data.CaseInsensitive as CI
6362import Data.Foldable (foldl')
6463import Data.Function (on)
6564import Data.Hashable
66−import qualified Data.HashMap.Strict as Map
6765import Data.List (intersperse)
6866import Data.List (elemIndex, nub, sortOn)
6967import Data.Semigroup hiding (Sum)
@@ -73,9 +71,7 @@ import qualified Data.Text as Text
7371import qualified Data.Text.Lazy.Builder as Build
7472import Data.Text.Manipulate
7573import Formatting
76−import Gen.Orphans ()
7774import Gen.Text
78−import Gen.Types.Map
7975import GHC.Generics (Generic)
8076import Language.Haskell.Exts.Build
8177import Language.Haskell.Exts.Syntax (Exp, Name (..))
@@ -164,22 +160,28 @@ instance IsString Global where
164160instance FromJSON Global where
165161 parseJSON = withText "global" (pure . mkGlobal)
166162
163+instance FromJSONKey Global where
164+ fromJSONKey = FromJSONKeyText mkGlobal
165+
167166instance ToJSON Global where
168167 toJSON = toJSON . global
169168
170−instance FromJSON v => FromJSON (Map Global v) where
171− parseJSON = fmap (Map.fromList . map (first mkGlobal) . Map.toList)
172− . parseJSON
173−
174169gid :: Format a (Global -> a)
175170gid = later (Build.fromText . global)
176171
177172newtype Local = Local { local :: Text }
178− deriving (Eq, Ord, Show, Generic, Hashable, FromJSON, ToJSON, IsString)
179−
180−instance FromJSON v => FromJSON (Map Local v) where
181− parseJSON = fmap (Map.fromList . map (first Local) . Map.toList)
182− . parseJSON
173+ deriving
174+ ( Eq
175+ , Ord
176+ , Show
177+ , Generic
178+ , Hashable
179+ , FromJSON
180+ , ToJSON
181+ , FromJSONKey
182+ , ToJSONKey
183+ , IsString
184+ )
183185
184186lid :: Format a (Local -> a)
185187lid = later (Build.fromText . local)
gen/src/Gen/Types/Schema.hs−1
@@ -38,7 +38,6 @@ import Data.Semigroup ((<>))
3838import Data.Text (Text)
3939import qualified Data.Text as Text
4040import Data.Text.Manipulate
41−import Gen.Orphans ()
4241import Gen.Text
4342import Gen.TH
4443import Gen.Types.Help
gen/src/Main.hs+2−1
@@ -18,6 +18,7 @@ import Control.Error
1818import Control.Lens hiding ((<.>))
1919import Control.Monad.State
2020import Data.List (nub, sort)
21+import Data.Monoid ((<>))
2122import Data.String
2223import qualified Data.Text as Text
2324import qualified Filesystem as FS
@@ -152,7 +153,7 @@ main = do
152153 let anx = _optAnnexes </> fromText modelName <.> "json"
153154 p <- isFile anx
154155 if not p
155− then say ("Skipping '" % stext % "' due to mimsing annex configuration.")
156+ then say ("Skipping '" % stext % "' due to missing annex configuration.")
156157 modelName
157158 else do
158159 s <- sequence
gen/stack.yaml+2
@@ -5,6 +5,8 @@ flags: {}
55
66extra-deps:
77 - text-regex-replace-0.1.1.1
8+ - haskell-src-exts-1.17.1
9+ - hindent-4.6.4
810
911packages:
1012 - '.'