@@ -18,7 +18,6 @@ import Control.Applicative
1818import Data.Bits
1919import Data.Word
2020import Foreign.Storable
21−import System.Random
2221import Data.Traversable (traverse)
2322import Data.Foldable (traverse_)
2423
@@ -262,8 +261,8 @@ prop_fail lbs errMsg0 = forAll (choose (0, 8 * L.length lbs)) $ \len ->
262261 expectedBytesConsumed
263262 | bits == 0 = bytes
264263 | otherwise = bytes + 1
265− p = do getByteString (fromIntegral bytes)
266− getBits (fromIntegral bits) :: BitGet Word8
264+ p = do _ <- getByteString (fromIntegral bytes)
265+ _ <- getBits (fromIntegral bits) :: BitGet Word8
267266 fail errMsg0
268267 r = runGetIncremental (runBitGet p) `pushChunks` lbs
269268 in case r of
@@ -395,11 +394,6 @@ instance (Arbitrary (W a), Arbitrary (W b), Arbitrary (W c)) => Arbitrary (W (a,
395394 arbitrary = ((W .) .) . (,,) <$> arbitraryW <*> arbitraryW <*> arbitraryW
396395 shrink (W (a,b,c)) = ((W .) .) . (,,) <$> shrinkW a <*> shrinkW b <*> shrinkW c
397396
398−integralRandomR :: (Integral a, RandomGen g) => (a,a) -> g -> (a,g)
399−integralRandomR (a,b) g = case randomR (fromIntegral a :: Integer,
400− fromIntegral b :: Integer) g of
401− (x,g) -> (fromIntegral x, g)
402−
403397data Primitive
404398 = Bool Bool
405399 | W8 Int Word8
@@ -408,6 +402,7 @@ data Primitive
408402 | W64 Int Word64
409403 | BS Int B.ByteString
410404 | LBS Int L.ByteString
405+ | Skip Int
411406 | IsEmpty
412407 deriving (Eq, Show)
413408
@@ -426,6 +421,7 @@ instance Arbitrary Primitive where
426421 , gen W16
427422 , gen W32
428423 , gen W64
424+ , Skip <$> choose (0, 3000)
429425 , do n <- choose (0,10)
430426 cs <- vector n
431427 return (BS n (B.pack cs))
@@ -442,6 +438,7 @@ instance Arbitrary Primitive where
442438 W16 _ x -> snk W16 x
443439 W32 _ x -> snk W32 x
444440 W64 _ x -> snk W64 x
441+ Skip x -> Skip <$> shrink x
445442 BS _ bs -> let ws = B.unpack bs in map (\ws' -> BS (length ws') (B.pack ws')) (shrink ws)
446443 LBS _ lbs -> let ws = L.unpack lbs in map (\ws' -> LBS (length ws') (L.pack ws')) (shrink ws)
447444 IsEmpty -> []
@@ -478,6 +475,7 @@ putPrimitive p =
478475 W16 n x -> putWord16 n x
479476 W32 n x -> putWord32 n x
480477 W64 n x -> putWord64 n x
478+ Skip n -> skipBits n
481479 BS _ bs -> putByteString bs
482480 LBS _ lbs -> mapM_ putByteString (L.toChunks lbs)
483481 IsEmpty -> return ()
@@ -490,10 +488,22 @@ getPrimitive p =
490488 W16 n _ -> W16 n <$> getWord16 n
491489 W32 n _ -> W32 n <$> getWord32 n
492490 W64 n _ -> W64 n <$> getWord64 n
491+ Skip n -> skipBits n >> return (Skip n)
493492 BS n _ -> BS n <$> getByteString n
494493 LBS n _ -> LBS n <$> getLazyByteString n
495494 IsEmpty -> isEmpty >> return IsEmpty
496495
496+getPrimitiveSize :: Primitive -> Int
497+getPrimitiveSize p = case p of
498+ Bool _ -> 1
499+ W8 n _ -> n
500+ W16 n _ -> n
501+ W32 n _ -> n
502+ W64 n _ -> n
503+ Skip n -> n
504+ BS n _ -> n*8
505+ LBS n _ -> n*8
506+ IsEmpty -> 0
497507
498508verifyProgram :: Int -> Program -> BitGet Bool
499509verifyProgram totalLength ps0 = go 0 ps0
@@ -501,13 +511,6 @@ verifyProgram totalLength ps0 = go 0 ps0
501511 go _ [] = return True
502512 go pos (p:ps) =
503513 case p of
504− Bool x -> check x getBool >> go (pos+1) ps
505− W8 n x -> check x (getWord8 n) >> go (pos+n) ps
506− W16 n x -> check x (getWord16 n) >> go (pos+n) ps
507− W32 n x -> check x (getWord32 n) >> go (pos+n) ps
508− W64 n x -> check x (getWord64 n) >> go (pos+n) ps
509− BS n x -> check x (getByteString n) >> go (pos+(8*n)) ps
510− LBS n x -> check x (getLazyByteString n) >> go (pos+(8*n)) ps
511514 IsEmpty -> do
512515 let expected = pos == totalLength
513516 actual <- isEmpty
@@ -515,6 +518,7 @@ verifyProgram totalLength ps0 = go 0 ps0
515518 then go pos ps
516519 else error $ "isEmpty returned wrong value, expected "
517520 ++ show expected ++ " but got " ++ show actual
521+ _ -> check p (getPrimitive p) >> go (pos + getPrimitiveSize p) ps
518522 check x g = do
519523 y <- g
520524 if x == y