@@ -72,7 +72,7 @@ import Data.Monoid (Dual(..), First(..), Last(..))
7272import Data.Ratio (Ratio, (%), numerator, denominator)
7373import Data.Scientific (Scientific)
7474import Data.Text (Text, pack, unpack)
75−import Data.Time (Day, LocalTime, UTCTime, ZonedTime)
75+import Data.Time (Day, LocalTime, NominalDiffTime, UTCTime, ZonedTime)
7676import Data.Time.Format (FormatTime, formatTime, parseTime)
7777import Data.Traversable as Tr (sequence, traverse)
7878import Data.Vector (Vector)
@@ -749,6 +749,21 @@ stringEncoding = String . T.decodeLatin1 . L.toStrict . encode
749749instance FromJSON UTCTime where
750750 parseJSON = withText "UTCTime" (Time.run Time.utcTime)
751751
752+instance ToJSON NominalDiffTime where
753+ toJSON = Number . realToFrac
754+ {-# INLINE toJSON #-}
755+
756+ toEncoding = Encoding . E.number . realToFrac
757+ {-# INLINE toEncoding #-}
758+
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
762+-- @1e1000000000@.
763+instance FromJSON NominalDiffTime where
764+ parseJSON = withScientific "NominalDiffTime" $ pure . realToFrac
765+ {-# INLINE parseJSON #-}
766+
752767parseJSONElemAtIndex :: FromJSON a => Int -> Vector Value -> Parser a
753768parseJSONElemAtIndex idx ary = parseJSON (V.unsafeIndex ary idx) <?> Index idx
754769