fix hexadecimal string generation to be hopefully (much) safer.
This commit is contained in:
parent
edc75500d3
commit
cc26ce8ce4
@ -11,6 +11,7 @@
|
|||||||
{-# LANGUAGE UnboxedTuples #-}
|
{-# LANGUAGE UnboxedTuples #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE BangPatterns #-}
|
{-# LANGUAGE BangPatterns #-}
|
||||||
|
{-# LANGUAGE Rank2Types #-}
|
||||||
module Crypto.Internal.Hex
|
module Crypto.Internal.Hex
|
||||||
( showHexadecimal
|
( showHexadecimal
|
||||||
, toHexadecimal
|
, toHexadecimal
|
||||||
@ -21,24 +22,42 @@ import Data.Word
|
|||||||
import GHC.Prim
|
import GHC.Prim
|
||||||
import GHC.Types
|
import GHC.Types
|
||||||
import GHC.Word
|
import GHC.Word
|
||||||
|
import Control.Monad
|
||||||
import Foreign.Storable
|
import Foreign.Storable
|
||||||
import Foreign.Ptr (Ptr)
|
import Foreign.Ptr (Ptr)
|
||||||
|
|
||||||
showHexadecimal :: Ptr Word8 -> Int -> String
|
showHexadecimal :: (forall a . (Ptr Word8 -> IO a) -> IO a) -> Int -> String
|
||||||
showHexadecimal ptr len = loop 0
|
showHexadecimal withPtr = doChunks 0
|
||||||
where
|
where
|
||||||
loop i
|
doChunks ofs len
|
||||||
| i == len = []
|
| len < 4 = doUnique ofs len
|
||||||
|
| otherwise = do
|
||||||
|
let !(W8# a, W8# b, W8# c, W8# d) = unsafeDoIO $ withPtr (read4 ofs)
|
||||||
|
(# w1, w2 #) = convertByte a
|
||||||
|
(# w3, w4 #) = convertByte b
|
||||||
|
(# w5, w6 #) = convertByte c
|
||||||
|
(# w7, w8 #) = convertByte d
|
||||||
|
in wToChar w1 : wToChar w2 : wToChar w3 : wToChar w4
|
||||||
|
: wToChar w5 : wToChar w6 : wToChar w7 : wToChar w8
|
||||||
|
: doChunks (ofs + 4) (len - 4)
|
||||||
|
|
||||||
|
doUnique ofs len
|
||||||
|
| len == 0 = []
|
||||||
| otherwise =
|
| otherwise =
|
||||||
let !(W8# b) = byteIndex i
|
let !(W8# b) = unsafeDoIO $ withPtr (byteIndex ofs)
|
||||||
(# w1, w2 #) = convertByte b
|
(# w1, w2 #) = convertByte b
|
||||||
in wToChar w1 : wToChar w2 : loop (i+1)
|
in wToChar w1 : wToChar w2 : doUnique (ofs + 1) (len - 1)
|
||||||
|
|
||||||
|
read4 :: Int -> Ptr Word8 -> IO (Word8, Word8, Word8, Word8)
|
||||||
|
read4 ofs p =
|
||||||
|
liftM4 (,,,) (byteIndex ofs p) (byteIndex (ofs+1) p)
|
||||||
|
(byteIndex (ofs+2) p) (byteIndex (ofs+3) p)
|
||||||
|
|
||||||
wToChar :: Word# -> Char
|
wToChar :: Word# -> Char
|
||||||
wToChar w = toEnum (I# (word2Int# w))
|
wToChar w = toEnum (I# (word2Int# w))
|
||||||
|
|
||||||
byteIndex :: Int -> Word8
|
byteIndex :: Int -> Ptr Word8 -> IO Word8
|
||||||
byteIndex i = unsafeDoIO (peekByteOff ptr i)
|
byteIndex i p = peekByteOff p i
|
||||||
|
|
||||||
toHexadecimal :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()
|
toHexadecimal :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()
|
||||||
toHexadecimal bout bin n = loop 0
|
toHexadecimal bout bin n = loop 0
|
||||||
|
|||||||
@ -123,5 +123,5 @@ bytesIndex (Bytes m) (I# i) = unsafeDoIO $ IO $ \s ->
|
|||||||
{-# NOINLINE bytesIndex #-}
|
{-# NOINLINE bytesIndex #-}
|
||||||
|
|
||||||
bytesShowHex :: Bytes -> String
|
bytesShowHex :: Bytes -> String
|
||||||
bytesShowHex b = unsafeDoIO $ withPtr b $ \p -> return $ showHexadecimal p (bytesLength b)
|
bytesShowHex b = showHexadecimal (withPtr b) (bytesLength b)
|
||||||
{-# NOINLINE bytesShowHex #-}
|
{-# NOINLINE bytesShowHex #-}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user