[commit: packages/array] master: Data.Array.Base: Check for overflow in size calculations (cb2446d)
git at git.haskell.org
git at git.haskell.org
Thu Dec 15 23:50:40 UTC 2016
Repository : ssh://git@git.haskell.org/array
On branch : master
Link : http://git.haskell.org/packages/array.git/commitdiff/cb2446dfeafd63a9013be43689a66a499a7f0862
>---------------------------------------------------------------
commit cb2446dfeafd63a9013be43689a66a499a7f0862
Author: Ben Gamari <ben at smart-cactus.org>
Date: Tue Dec 6 20:38:59 2016 -0500
Data.Array.Base: Check for overflow in size calculations
Fixes GHC #4505.
>---------------------------------------------------------------
cb2446dfeafd63a9013be43689a66a499a7f0862
Data/Array/Base.hs | 44 ++++++++++++++++++++++++++++++--------------
tests/T229.hs | 9 +++++++++
tests/T229.stderr | 3 +++
tests/all.T | 2 +-
4 files changed, 43 insertions(+), 15 deletions(-)
diff --git a/Data/Array/Base.hs b/Data/Array/Base.hs
index 9908ad2..c88e272 100644
--- a/Data/Array/Base.hs
+++ b/Data/Array/Base.hs
@@ -1065,7 +1065,7 @@ instance MArray (STUArray s) Char (ST s) where
{-# INLINE getNumElements #-}
getNumElements (STUArray _ _ n _) = return n
{-# INLINE unsafeNewArray_ #-}
- unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (*# 4#)
+ unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (safe_scale 4#)
{-# INLINE newArray_ #-}
newArray_ arrBounds = newArray arrBounds (chr 0)
{-# INLINE unsafeRead #-}
@@ -1227,7 +1227,7 @@ instance MArray (STUArray s) Int16 (ST s) where
{-# INLINE getNumElements #-}
getNumElements (STUArray _ _ n _) = return n
{-# INLINE unsafeNewArray_ #-}
- unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (*# 2#)
+ unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (safe_scale 2#)
{-# INLINE newArray_ #-}
newArray_ arrBounds = newArray arrBounds 0
{-# INLINE unsafeRead #-}
@@ -1245,7 +1245,7 @@ instance MArray (STUArray s) Int32 (ST s) where
{-# INLINE getNumElements #-}
getNumElements (STUArray _ _ n _) = return n
{-# INLINE unsafeNewArray_ #-}
- unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (*# 4#)
+ unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (safe_scale 4#)
{-# INLINE newArray_ #-}
newArray_ arrBounds = newArray arrBounds 0
{-# INLINE unsafeRead #-}
@@ -1263,7 +1263,7 @@ instance MArray (STUArray s) Int64 (ST s) where
{-# INLINE getNumElements #-}
getNumElements (STUArray _ _ n _) = return n
{-# INLINE unsafeNewArray_ #-}
- unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (*# 8#)
+ unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (safe_scale 8#)
{-# INLINE newArray_ #-}
newArray_ arrBounds = newArray arrBounds 0
{-# INLINE unsafeRead #-}
@@ -1299,7 +1299,7 @@ instance MArray (STUArray s) Word16 (ST s) where
{-# INLINE getNumElements #-}
getNumElements (STUArray _ _ n _) = return n
{-# INLINE unsafeNewArray_ #-}
- unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (*# 2#)
+ unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (safe_scale 2#)
{-# INLINE newArray_ #-}
newArray_ arrBounds = newArray arrBounds 0
{-# INLINE unsafeRead #-}
@@ -1317,7 +1317,7 @@ instance MArray (STUArray s) Word32 (ST s) where
{-# INLINE getNumElements #-}
getNumElements (STUArray _ _ n _) = return n
{-# INLINE unsafeNewArray_ #-}
- unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (*# 4#)
+ unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (safe_scale 4#)
{-# INLINE newArray_ #-}
newArray_ arrBounds = newArray arrBounds 0
{-# INLINE unsafeRead #-}
@@ -1335,7 +1335,7 @@ instance MArray (STUArray s) Word64 (ST s) where
{-# INLINE getNumElements #-}
getNumElements (STUArray _ _ n _) = return n
{-# INLINE unsafeNewArray_ #-}
- unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (*# 8#)
+ unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) (safe_scale 8#)
{-# INLINE newArray_ #-}
newArray_ arrBounds = newArray arrBounds 0
{-# INLINE unsafeRead #-}
@@ -1352,13 +1352,29 @@ instance MArray (STUArray s) Word64 (ST s) where
bOOL_SCALE, bOOL_WORD_SCALE,
wORD_SCALE, dOUBLE_SCALE, fLOAT_SCALE :: Int# -> Int#
-bOOL_SCALE n# = (n# +# last#) `uncheckedIShiftRA#` 3#
- where !(I# last#) = SIZEOF_HSWORD * 8 - 1
-bOOL_WORD_SCALE n# = bOOL_INDEX (n# +# last#)
- where !(I# last#) = SIZEOF_HSWORD * 8 - 1
-wORD_SCALE n# = scale# *# n# where !(I# scale#) = SIZEOF_HSWORD
-dOUBLE_SCALE n# = scale# *# n# where !(I# scale#) = SIZEOF_HSDOUBLE
-fLOAT_SCALE n# = scale# *# n# where !(I# scale#) = SIZEOF_HSFLOAT
+bOOL_SCALE n#
+ | isTrue# (res# ># n#) = res#
+ | otherwise = error "Data.Array.Base.bOOL_SCALE: Overflow"
+ where
+ !(I# last#) = SIZEOF_HSWORD * 8 - 1
+ !res# = (n# +# last#) `uncheckedIShiftRA#` 3#
+bOOL_WORD_SCALE n#
+ | isTrue# (res# ># n#) = res#
+ | otherwise = error "Data.Array.Base.bOOL_WORD_SCALE: Overflow"
+ where
+ !(I# last#) = SIZEOF_HSWORD * 8 - 1
+ !res# = bOOL_INDEX (n# +# last#)
+wORD_SCALE n# = safe_scale scale# n# where !(I# scale#) = SIZEOF_HSWORD
+dOUBLE_SCALE n# = safe_scale scale# n# where !(I# scale#) = SIZEOF_HSDOUBLE
+fLOAT_SCALE n# = safe_scale scale# n# where !(I# scale#) = SIZEOF_HSFLOAT
+
+safe_scale :: Int# -> Int# -> Int#
+safe_scale scale# n#
+ | isTrue# (res# >=# n#) = res#
+ | otherwise = error "Data.Array.Base.safe_scale: Overflow"
+ where
+ !res# = scale# *# n#
+
bOOL_INDEX :: Int# -> Int#
#if SIZEOF_HSWORD == 4
diff --git a/tests/T229.hs b/tests/T229.hs
new file mode 100644
index 0000000..2265852
--- /dev/null
+++ b/tests/T229.hs
@@ -0,0 +1,9 @@
+import Data.Array.MArray
+import Data.Array.IO
+import Data.Word
+
+main :: IO ()
+main = do
+ -- This should fail due to integer overflow
+ m <- newArray_ (0,2^62-1) :: IO (IOUArray Int Word32) -- allocates 0 bytes
+ readArray m 17 >>= print -- Read some random location in address space
diff --git a/tests/T229.stderr b/tests/T229.stderr
new file mode 100644
index 0000000..deb6094
--- /dev/null
+++ b/tests/T229.stderr
@@ -0,0 +1,3 @@
+T229: Data.Array.Base.safe_scale: Overflow
+CallStack (from HasCallStack):
+ error, called at libraries/array/Data/Array/Base.hs:1374:17 in array-0.5.1.2:Data.Array.Base
diff --git a/tests/all.T b/tests/all.T
index 4fd4844..a5f92e7 100644
--- a/tests/all.T
+++ b/tests/all.T
@@ -1,4 +1,3 @@
-
test('T2120', normal, compile_and_run, [''])
test('largeArray', normal, compile_and_run, [''])
test('array001', [
@@ -7,3 +6,4 @@ test('array001', [
compile_and_run, [''])
test('T9220', normal, ghci_script, ['T9220.script'])
+test('T229', [exit_code(1)], compile_and_run, [''])
More information about the ghc-commits
mailing list