Skip to content
Permalink
Browse files

Reject numbers that contain leading zeros (gh-480)

This is forbidden by RFC 7159, probably because a JS engine may
interpret such a number as octal (!!!).

This bug was exposed by JSONTestSuite.  Hooray JSONTestSuite!
  • Loading branch information...
bos committed Oct 28, 2016
1 parent b87d021 commit 3fb7c155f2255482b1b9566ec5c1eaf9895d630e
Showing with 11 additions and 2 deletions.
  1. +11 −1 Data/Aeson/Parser/Internal.hs
  2. +0 −1 tests/UnitTests.hs
@@ -46,6 +46,7 @@ import Data.Vector as Vector (Vector, empty, fromListN, reverse)
import qualified Data.Attoparsec.ByteString as A
import qualified Data.Attoparsec.Lazy as L
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as B
import qualified Data.ByteString.Lazy as L
import qualified Data.HashMap.Strict as H
import qualified Data.Scientific as Sci
@@ -299,6 +300,15 @@ jsonEOF' = json' <* skipSpace <* endOfInput
-- A strict pair
data SP = SP !Integer {-# UNPACK #-}!Int

decimal0 :: Parser Integer
decimal0 = do
let step a w = a * 10 + fromIntegral (w - zero)
zero = 48
digits <- A.takeWhile1 isDigit_w8
if B.length digits > 1 && B.unsafeHead digits == zero
then fail "leading zero"
else return (B.foldl' step 0 digits)

{-# INLINE scientific #-}
scientific :: Parser Scientific
scientific = do
@@ -309,7 +319,7 @@ scientific = do
when (sign == plus || sign == minus) $
void A.anyWord8

n <- decimal
n <- decimal0

let f fracDigits = SP (B.foldl' step n fracDigits)
(negate $ B.length fracDigits)
@@ -667,7 +667,6 @@ _blacklist = HashSet.fromList [
, "i_string_not_in_unicode_range.json"
, "i_string_truncated-utf-8.json"
, "i_structure_UTF-8_BOM_empty_object.json"
, "n_number_-01.json"
, "n_number_-2..json"
, "n_number_0.e1.json"
, "n_number_2.e+3.json"

0 comments on commit 3fb7c15

Please sign in to comment.
You can’t perform that action at this time.