diff --git a/Data/ByteString/Internal/Type.hs b/Data/ByteString/Internal/Type.hs index f43e983ac..67c187e3e 100644 --- a/Data/ByteString/Internal/Type.hs +++ b/Data/ByteString/Internal/Type.hs @@ -137,6 +137,8 @@ import Foreign.Marshal.Utils #if PURE_HASKELL import qualified Data.ByteString.Internal.Pure as Pure +import Data.Bits (toIntegralSized, Bits) +import Data.Maybe (fromMaybe) #endif #if !MIN_VERSION_base(4,13,0) @@ -1220,44 +1222,44 @@ foreign import ccall safe "bytestring_is_valid_utf8" cIsValidUtf8Safe -- | Reverse n-bytes from the second pointer into the first c_reverse :: Ptr Word8 -> Ptr Word8 -> CSize -> IO () -c_reverse p1 p2 sz = Pure.reverseBytes p1 p2 (fromIntegral sz) +c_reverse p1 p2 sz = Pure.reverseBytes p1 p2 (checkedCast sz) -- | find maximum char in a packed string c_maximum :: Ptr Word8 -> CSize -> IO Word8 -c_maximum ptr sz = Pure.findMaximum ptr (fromIntegral sz) +c_maximum ptr sz = Pure.findMaximum ptr (checkedCast sz) -- | find minimum char in a packed string c_minimum :: Ptr Word8 -> CSize -> IO Word8 -c_minimum ptr sz = Pure.findMinimum ptr (fromIntegral sz) +c_minimum ptr sz = Pure.findMinimum ptr (checkedCast sz) -- | count the number of occurrences of a char in a string c_count :: Ptr Word8 -> CSize -> Word8 -> IO CSize -c_count ptr sz c = fromIntegral <$> Pure.countOcc ptr (fromIntegral sz) c +c_count ptr sz c = checkedCast <$> Pure.countOcc ptr (checkedCast sz) c -- | count the number of occurrences of a char in a string c_count_ba :: ByteArray# -> Int -> Word8 -> IO CSize -c_count_ba ba o c = fromIntegral <$> Pure.countOccBA ba o c +c_count_ba ba o c = checkedCast <$> Pure.countOccBA ba o c -- | duplicate a string, interspersing the character through the elements of the -- duplicated string c_intersperse :: Ptr Word8 -> Ptr Word8 -> CSize -> Word8 -> IO () -c_intersperse p1 p2 sz e = Pure.intersperse p1 p2 (fromIntegral sz) e +c_intersperse p1 p2 sz e = Pure.intersperse p1 p2 (checkedCast sz) e -- | Quick sort bytes c_sort :: Ptr Word8 -> CSize -> IO () -c_sort ptr sz = Pure.quickSort ptr (fromIntegral sz) +c_sort ptr sz = Pure.quickSort ptr (checkedCast sz) c_elem_index :: ByteArray# -> Word8 -> CSize -> IO CPtrdiff -c_elem_index ba e sz = fromIntegral <$> Pure.elemIndex ba e (fromIntegral sz) +c_elem_index ba e sz = checkedCast <$> Pure.elemIndex ba e (checkedCast sz) cIsValidUtf8BA :: ByteArray# -> CSize -> IO CInt -cIsValidUtf8BA ba sz = bool_to_cint <$> Pure.isValidUtf8BA ba (fromIntegral sz) +cIsValidUtf8BA ba sz = bool_to_cint <$> Pure.isValidUtf8BA ba (checkedCast sz) cIsValidUtf8BASafe :: ByteArray# -> CSize -> IO CInt cIsValidUtf8BASafe = cIsValidUtf8BA cIsValidUtf8 :: Ptr Word8 -> CSize -> IO CInt -cIsValidUtf8 ptr sz = bool_to_cint <$> Pure.isValidUtf8 ptr (fromIntegral sz) +cIsValidUtf8 ptr sz = bool_to_cint <$> Pure.isValidUtf8 ptr (checkedCast sz) cIsValidUtf8Safe :: Ptr Word8 -> CSize -> IO CInt cIsValidUtf8Safe = cIsValidUtf8 @@ -1266,6 +1268,11 @@ bool_to_cint :: Bool -> CInt bool_to_cint True = 1 bool_to_cint False = 0 +checkedCast :: (Bits a, Bits b, Integral a, Integral b) => a -> b +checkedCast x = + fromMaybe (errorWithoutStackTrace "checkedCast: overflow") + (toIntegralSized x) + ---------------------------------------------------------------- -- Haskell version of functions in itoa.c ----------------------------------------------------------------