@@ -77,7 +77,7 @@ import Data.Maybe (fromMaybe)
77import Data.Monoid (Dual(..), First(..), Last(..))
77import Data.Monoid (Dual(..), First(..), Last(..))
78import Data.Ratio (Ratio, (%), numerator, denominator)
78import Data.Ratio (Ratio, (%), numerator, denominator)
79import Data.Text (Text, pack, unpack)
79import Data.Text (Text, pack, unpack)
80−import Data.Time (Day, LocalTime, UTCTime, ZonedTime)
80+import Data.Time (Day, LocalTime, UTCTime, ZonedTime, NominalDiffTime)
81import Data.Time.Format (FormatTime, formatTime, parseTime)
81import Data.Time.Format (FormatTime, formatTime, parseTime)
82import Data.Traversable as Tr (sequence, traverse)
82import Data.Traversable as Tr (sequence, traverse)
83import Data.Vector (Vector)
83import Data.Vector (Vector)
@@ -749,6 +749,21 @@ stringEncoding = String . T.decodeLatin1 . L.toStrict . encode
749instance FromJSON UTCTime where
749instance FromJSON UTCTime where
750 parseJSON = withText "UTCTime" (Time.run Time.utcTime)
750 parseJSON = withText "UTCTime" (Time.run Time.utcTime)
752+instance ToJSON NominalDiffTime where
753+ toJSON = Number . realToFrac
754+ {-# INLINE toJSON #-}
756+ toEncoding = Encoding . E.number . realToFrac
757+ {-# INLINE toEncoding #-}
759+-- | /WARNING:/ Only parse lengths of time from trusted input
760+-- since an attacker could easily fill up the memory of the target
761+-- system by specifying a scientific number with a big exponent like
763+instance FromJSON NominalDiffTime where
764+ parseJSON = withScientific "NominalDiffTime" $ pure . realToFrac
765+ {-# INLINE parseJSON #-}
752parseJSONElemAtIndex :: FromJSON a => Int -> Vector Value -> Parser a
767parseJSONElemAtIndex :: FromJSON a => Int -> Vector Value -> Parser a
753parseJSONElemAtIndex idx ary = parseJSON (V.unsafeIndex ary idx) <?> Index idx
768parseJSONElemAtIndex idx ary = parseJSON (V.unsafeIndex ary idx) <?> Index idx