Skip to content

Commit 56ccd68

Browse files
committed
Catch 0 denominators when parsing Ratio
1 parent bc0146d commit 56ccd68

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

Data/Aeson/Types/FromJSON.hs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,9 +1258,12 @@ instance FromJSONKey Float where
12581258
_ -> Scientific.toRealFloat <$> parseScientificText t
12591259

12601260
instance (FromJSON a, Integral a) => FromJSON (Ratio a) where
1261-
parseJSON = withObject "Rational" $ \obj ->
1262-
(%) <$> obj .: "numerator"
1263-
<*> obj .: "denominator"
1261+
parseJSON = withObject "Rational" $ \obj -> do
1262+
numerator <- obj .: "numerator"
1263+
denominator <- obj .: "denominator"
1264+
if denominator == 0
1265+
then fail "Ratio denominator was 0"
1266+
else pure $ numerator % denominator
12641267
{-# INLINE parseJSON #-}
12651268

12661269
-- | /WARNING:/ Only parse fixed-precision numbers from trusted input

tests/UnitTests.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ tests = testGroup "unit" [
100100
, testGroup "SingleMaybeField" singleMaybeField
101101
, testCase "withEmbeddedJSON" withEmbeddedJSONTest
102102
, testCase "SingleFieldCon" singleFieldCon
103+
, testCase "Ratio with denominator 0" ratioDenominator0
103104
]
104105

105106
roundTripCamel :: String -> Assertion
@@ -546,6 +547,12 @@ singleFieldCon :: Assertion
546547
singleFieldCon =
547548
assertEqual "fromJSON" (Right (SingleFieldCon 0)) (eitherDecode "0")
548549

550+
ratioDenominator0 :: Assertion
551+
ratioDenominator0 =
552+
assertEqual "Ratio with denominator 0"
553+
(Left "Error in $: Ratio denominator was 0")
554+
(eitherDecode "{ \"numerator\": 1, \"denominator\": 0 }" :: Either String Rational)
555+
549556
deriveJSON defaultOptions{omitNothingFields=True} ''MyRecord
550557

551558
deriveToJSON defaultOptions ''Foo

0 commit comments

Comments
 (0)