hackage-security-0.6.3.2: Hackage security library

Copyright | (c) Galois Inc. 2007-2009 Duncan Coutts 2015
Safe Haskell | None
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 Source #

Constructors

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

#### Instances

Instances details

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

data Int54 Source #

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

PrintfArg Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods formatArg :: Int54 -> FieldFormatter Source # parseFormat :: Int54 -> ModifierParser Source #
Bits Int54 Source # |

Instance details

Defined in Text.JSON.Canonical

Methods

(.&.) :: Int54 -> Int54 -> Int54 Source #

(.|.) :: Int54 -> Int54 -> Int54 Source #

xor :: Int54 -> Int54 -> Int54 Source #

complement :: Int54 -> Int54 Source #

shift :: Int54 -> Int -> Int54 Source #

rotate :: Int54 -> Int -> Int54 Source #

zeroBits :: Int54 Source #

bit :: Int -> Int54 Source #

setBit :: Int54 -> Int -> Int54 Source #

clearBit :: Int54 -> Int -> Int54 Source #

complementBit :: Int54 -> Int -> Int54 Source #

testBit :: Int54 -> Int -> Bool Source #

bitSizeMaybe :: Int54 -> Maybe Int Source #

bitSize :: Int54 -> Int Source #

isSigned :: Int54 -> Bool Source #

shiftL :: Int54 -> Int -> Int54 Source #

unsafeShiftL :: Int54 -> Int -> Int54 Source #

shiftR :: Int54 -> Int -> Int54 Source #

unsafeShiftR :: Int54 -> Int -> Int54 Source #

rotateL :: Int54 -> Int -> Int54 Source #

rotateR :: Int54 -> Int -> Int54 Source #

popCount :: Int54 -> Int Source #

FiniteBits Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods finiteBitSize :: Int54 -> Int Source # countLeadingZeros :: Int54 -> Int Source # countTrailingZeros :: Int54 -> Int Source #
Data Int54 Source # |

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 Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Int54 Source #

toConstr :: Int54 -> Constr Source #

dataTypeOf :: Int54 -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Int54) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Int54) Source #

gmapT :: (forall b. Data b => b -> b) -> Int54 -> Int54 Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Int54 -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Int54 -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> Int54 -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Int54 -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Int54 -> m Int54 Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Int54 -> m Int54 Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Int54 -> m Int54 Source #

Bounded Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods minBound :: Int54 Source # maxBound :: Int54 Source #
Enum Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods succ :: Int54 -> Int54 Source # pred :: Int54 -> Int54 Source # toEnum :: Int -> Int54 Source # fromEnum :: Int54 -> Int Source # enumFrom :: Int54 -> [Int54] Source # enumFromThen :: Int54 -> Int54 -> [Int54] Source # enumFromTo :: Int54 -> Int54 -> [Int54] Source # enumFromThenTo :: Int54 -> Int54 -> Int54 -> [Int54] Source #
Storable Int54 Source # |

Instance details

Defined in Text.JSON.Canonical

Methods

sizeOf :: Int54 -> Int Source #

alignment :: Int54 -> Int Source #

peekElemOff :: Ptr Int54 -> Int -> IO Int54 Source #

pokeElemOff :: Ptr Int54 -> Int -> Int54 -> IO () Source #

peekByteOff :: Ptr b -> Int -> IO Int54 Source #

pokeByteOff :: Ptr b -> Int -> Int54 -> IO () Source #

peek :: Ptr Int54 -> IO Int54 Source #

poke :: Ptr Int54 -> Int54 -> IO () Source #

Ix Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods range :: (Int54, Int54) -> [Int54] Source # index :: (Int54, Int54) -> Int54 -> Int Source # unsafeIndex :: (Int54, Int54) -> Int54 -> Int Source # inRange :: (Int54, Int54) -> Int54 -> Bool Source # rangeSize :: (Int54, Int54) -> Int Source # unsafeRangeSize :: (Int54, Int54) -> Int Source #
Num Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods (+) :: Int54 -> Int54 -> Int54 Source # (-) :: Int54 -> Int54 -> Int54 Source # (*) :: Int54 -> Int54 -> Int54 Source # negate :: Int54 -> Int54 Source # abs :: Int54 -> Int54 Source # signum :: Int54 -> Int54 Source # fromInteger :: Integer -> Int54 Source #
Read Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods readsPrec :: Int -> ReadS Int54 Source # readList :: ReadS [Int54] Source # readPrec :: ReadPrec Int54 Source # readListPrec :: ReadPrec [Int54] Source #
Integral Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods quot :: Int54 -> Int54 -> Int54 Source # rem :: Int54 -> Int54 -> Int54 Source # div :: Int54 -> Int54 -> Int54 Source # mod :: Int54 -> Int54 -> Int54 Source # quotRem :: Int54 -> Int54 -> (Int54, Int54) Source # divMod :: Int54 -> Int54 -> (Int54, Int54) Source # toInteger :: Int54 -> Integer Source #
Real Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods toRational :: Int54 -> Rational Source #
Show Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods showsPrec :: Int -> Int54 -> ShowS Source # show :: Int54 -> String Source # showList :: [Int54] -> ShowS Source #
Eq Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods (==) :: Int54 -> Int54 -> Bool Source # (/=) :: Int54 -> Int54 -> Bool Source #
Ord Int54 Source # |
Instance details Defined in Text.JSON.Canonical Methods compare :: Int54 -> Int54 -> Ordering Source # (<) :: Int54 -> Int54 -> Bool Source # (<=) :: Int54 -> Int54 -> Bool Source # (>) :: Int54 -> Int54 -> Bool Source # (>=) :: Int54 -> Int54 -> Bool Source # max :: Int54 -> Int54 -> Int54 Source # min :: Int54 -> Int54 -> Int54 Source #
ReportSchemaErrors m => FromJSON m Int54 Source # |
Instance details Defined in Hackage.Security.Util.JSON Methods fromJSON :: JSValue -> m Int54 Source #
Monad m => ToJSON m Int54 Source # |
Instance details Defined in Hackage.Security.Util.JSON Methods toJSON :: Int54 -> m JSValue Source #

parseCanonicalJSON :: ByteString -> Either String JSValue Source #

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 Source #

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 Source #

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.