hackage-security-0.6.2.3: Hackage security library

Copyright | (c) Galois Inc. 2007-2009 Duncan Coutts 2015
Safe Haskell | Safe-Inferred
Language | Haskell2010

Text.JSON.Canonical

Description

Minimal implementation of Canonical JSON.

http://wiki.laptop.org/go/Canonical_JSON

A "canonical JSON" format is provided in order to provide meaningful and repeatable hashes of JSON-encoded data. Canonical JSON is parsable with any full JSON parser, but security-conscious applications will want to verify that input is in canonical form before authenticating any hash or signature on that input.

This implementation is derived from the json parser from the json package, with simplifications to meet the Canonical JSON grammar.

TODO: Known bugs/limitations:

- Decoding/encoding Unicode code-points beyond `U+00ff` is currently broken

Synopsis

- data JSValue
  - = JSNull
  - | JSBool !Bool
  - | JSNum !Int54
  - | JSString String
  - | JSArray [JSValue]
  - | JSObject [(String, JSValue)]
- data Int54
- parseCanonicalJSON :: ByteString -> Either String JSValue
- renderCanonicalJSON :: JSValue -> ByteString
- prettyCanonicalJSON :: JSValue -> String

# Documentation

data JSValue #

Constructors

JSNull |
JSBool !Bool |
JSNum !Int54 |
JSString String |
JSArray [JSValue] |
JSObject [(String, JSValue)] |

#### Instances

Instances details

Read JSValue # |
Instance details Defined in Text.JSON.Canonical Methods readsPrec :: Int -> ReadS JSValue readList :: ReadS [JSValue] readPrec :: ReadPrec JSValue readListPrec :: ReadPrec [JSValue]
Show JSValue # |
Instance details Defined in Text.JSON.Canonical Methods showsPrec :: Int -> JSValue -> ShowS show :: JSValue -> String showList :: [JSValue] -> ShowS
Eq JSValue # |
Instance details Defined in Text.JSON.Canonical Methods (==) :: JSValue -> JSValue -> Bool (/=) :: JSValue -> JSValue -> Bool
Ord JSValue # |
Instance details Defined in Text.JSON.Canonical Methods compare :: JSValue -> JSValue -> Ordering (<) :: JSValue -> JSValue -> Bool (<=) :: JSValue -> JSValue -> Bool (>) :: JSValue -> JSValue -> Bool (>=) :: JSValue -> JSValue -> Bool max :: JSValue -> JSValue -> JSValue min :: JSValue -> JSValue -> JSValue
Monad m => FromJSON m JSValue # |
Instance details Defined in Hackage.Security.Util.JSON Methods fromJSON :: JSValue -> m JSValue #
Monad m => ToJSON m JSValue # |
Instance details Defined in Hackage.Security.Util.JSON Methods toJSON :: JSValue -> m JSValue #

data Int54 #

54-bit integer values

JavaScript can only safely represent numbers between `-(2^53 - 1)` and `2^53 - 1`.

TODO: Although we introduce the type here, we don't actually do any bounds checking and just inherit all type class instance from Int64. We should probably define `fromInteger` to do bounds checking, give different instances for type classes such as `Bounded` and `FiniteBits`, etc.

#### Instances

Instances details

Data Int54 # |
Instance details Defined in Text.JSON.Canonical Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Int54 -> c Int54 gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Int54 toConstr :: Int54 -> Constr dataTypeOf :: Int54 -> DataType dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Int54) dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Int54) gmapT :: (forall b. Data b => b -> b) -> Int54 -> Int54 gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Int54 -> r gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Int54 -> r gmapQ :: (forall d. Data d => d -> u) -> Int54 -> [u] gmapQi :: Int -> (forall d. Data d => d -> u) -> Int54 -> u gmapM :: Monad m => (forall d. Data d => d -> m d) -> Int54 -> m Int54 gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Int54 -> m Int54 gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Int54 -> m Int54
Storable Int54 # |
Instance details Defined in Text.JSON.Canonical Methods sizeOf :: Int54 -> Int alignment :: Int54 -> Int peekElemOff :: Ptr Int54 -> Int -> IO Int54 pokeElemOff :: Ptr Int54 -> Int -> Int54 -> IO () peekByteOff :: Ptr b -> Int -> IO Int54 pokeByteOff :: Ptr b -> Int -> Int54 -> IO () peek :: Ptr Int54 -> IO Int54 poke :: Ptr Int54 -> Int54 -> IO ()
Bits Int54 # |
Instance details Defined in Text.JSON.Canonical Methods (.&.) :: Int54 -> Int54 -> Int54 (.|.) :: Int54 -> Int54 -> Int54 xor :: Int54 -> Int54 -> Int54 complement :: Int54 -> Int54 shift :: Int54 -> Int -> Int54 rotate :: Int54 -> Int -> Int54 zeroBits :: Int54 bit :: Int -> Int54 setBit :: Int54 -> Int -> Int54 clearBit :: Int54 -> Int -> Int54 complementBit :: Int54 -> Int -> Int54 testBit :: Int54 -> Int -> Bool bitSizeMaybe :: Int54 -> Maybe Int bitSize :: Int54 -> Int isSigned :: Int54 -> Bool shiftL :: Int54 -> Int -> Int54 unsafeShiftL :: Int54 -> Int -> Int54 shiftR :: Int54 -> Int -> Int54 unsafeShiftR :: Int54 -> Int -> Int54 rotateL :: Int54 -> Int -> Int54 rotateR :: Int54 -> Int -> Int54 popCount :: Int54 -> Int
FiniteBits Int54 # |
Instance details Defined in Text.JSON.Canonical Methods finiteBitSize :: Int54 -> Int countLeadingZeros :: Int54 -> Int countTrailingZeros :: Int54 -> Int
Bounded Int54 # |
Instance details Defined in Text.JSON.Canonical Methods minBound :: Int54 maxBound :: Int54
Enum Int54 # |
Instance details Defined in Text.JSON.Canonical Methods succ :: Int54 -> Int54 pred :: Int54 -> Int54 toEnum :: Int -> Int54 fromEnum :: Int54 -> Int enumFrom :: Int54 -> [Int54] enumFromThen :: Int54 -> Int54 -> [Int54] enumFromTo :: Int54 -> Int54 -> [Int54] enumFromThenTo :: Int54 -> Int54 -> Int54 -> [Int54]
Ix Int54 # |
Instance details Defined in Text.JSON.Canonical Methods range :: (Int54, Int54) -> [Int54] index :: (Int54, Int54) -> Int54 -> Int unsafeIndex :: (Int54, Int54) -> Int54 -> Int inRange :: (Int54, Int54) -> Int54 -> Bool rangeSize :: (Int54, Int54) -> Int unsafeRangeSize :: (Int54, Int54) -> Int
Num Int54 # |
Instance details Defined in Text.JSON.Canonical Methods (+) :: Int54 -> Int54 -> Int54 (-) :: Int54 -> Int54 -> Int54 (*) :: Int54 -> Int54 -> Int54 negate :: Int54 -> Int54 abs :: Int54 -> Int54 signum :: Int54 -> Int54 fromInteger :: Integer -> Int54
Read Int54 # |
Instance details Defined in Text.JSON.Canonical Methods readsPrec :: Int -> ReadS Int54 readList :: ReadS [Int54] readPrec :: ReadPrec Int54 readListPrec :: ReadPrec [Int54]
Integral Int54 # |
Instance details Defined in Text.JSON.Canonical Methods quot :: Int54 -> Int54 -> Int54 rem :: Int54 -> Int54 -> Int54 div :: Int54 -> Int54 -> Int54 mod :: Int54 -> Int54 -> Int54 quotRem :: Int54 -> Int54 -> (Int54, Int54) divMod :: Int54 -> Int54 -> (Int54, Int54) toInteger :: Int54 -> Integer
Real Int54 # |
Instance details Defined in Text.JSON.Canonical Methods toRational :: Int54 -> Rational
Show Int54 # |
Instance details Defined in Text.JSON.Canonical Methods showsPrec :: Int -> Int54 -> ShowS show :: Int54 -> String showList :: [Int54] -> ShowS
PrintfArg Int54 # |
Instance details Defined in Text.JSON.Canonical Methods formatArg :: Int54 -> FieldFormatter parseFormat :: Int54 -> ModifierParser
Eq Int54 # |
Instance details Defined in Text.JSON.Canonical Methods (==) :: Int54 -> Int54 -> Bool (/=) :: Int54 -> Int54 -> Bool
Ord Int54 # |
Instance details Defined in Text.JSON.Canonical Methods compare :: Int54 -> Int54 -> Ordering (<) :: Int54 -> Int54 -> Bool (<=) :: Int54 -> Int54 -> Bool (>) :: Int54 -> Int54 -> Bool (>=) :: Int54 -> Int54 -> Bool max :: Int54 -> Int54 -> Int54 min :: Int54 -> Int54 -> Int54
ReportSchemaErrors m => FromJSON m Int54 # |
Instance details Defined in Hackage.Security.Util.JSON Methods fromJSON :: JSValue -> m Int54 #
Monad m => ToJSON m Int54 # |
Instance details Defined in Hackage.Security.Util.JSON Methods toJSON :: Int54 -> m JSValue #

parseCanonicalJSON :: ByteString -> Either String JSValue #

Parse a canonical JSON format string as a JSON value. The input string does not have to be in canonical form, just in the "canonical JSON" format.

Use `renderCanonicalJSON` to convert into canonical form.

renderCanonicalJSON :: JSValue -> ByteString #

Render a JSON value in canonical form. This rendered form is canonical and so allows repeatable hashes.

For pretty printing, see prettyCanonicalJSON.

NB: Canonical JSON's string escaping rules deviate from RFC 7159 JSON which requires

"All Unicode characters may be placed within the quotation marks, except for the characters that must be escaped: quotation mark, reverse solidus, and the control characters (`U+0000` through `U+001F`)."

Whereas the current specification of Canonical JSON explicitly requires to violate this by only escaping the quotation mark and the reverse solidus. This, however, contradicts Canonical JSON's statement that "Canonical JSON is parsable with any full JSON parser"

Consequently, Canonical JSON is not a proper subset of RFC 7159.

prettyCanonicalJSON :: JSValue -> String #

Render a JSON value in a reasonable human-readable form. This rendered form is not the canonical form used for repeatable hashes, use `renderCanonicalJSON` for that.