Skip to content

Commit ff2b020

Browse files
committed
Use BS.unsafeCreateFp in fromShort (#662)
This ensures that the result of `fromShort` is properly protected by a call to `mkDeferredByteString`. (cherry picked from commit 70fa96b)
1 parent e77df71 commit ff2b020

File tree

1 file changed

+10
-30
lines changed

1 file changed

+10
-30
lines changed

Data/ByteString/Short/Internal.hs

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,6 @@ import Foreign.C.Types
204204
, CInt(..)
205205
)
206206
#endif
207-
import Foreign.ForeignPtr
208-
( touchForeignPtr )
209-
import Foreign.ForeignPtr.Unsafe
210-
( unsafeForeignPtrToPtr )
211207
import Foreign.Marshal.Alloc
212208
( allocaBytes )
213209
import Foreign.Storable
@@ -217,7 +213,6 @@ import GHC.Exts
217213
, State#, RealWorld
218214
, ByteArray#, MutableByteArray#
219215
, newByteArray#
220-
, newPinnedByteArray#
221216
, byteArrayContents#
222217
, unsafeCoerce#
223218
, copyMutableByteArray#
@@ -487,30 +482,21 @@ toShort !bs = unsafeDupablePerformIO (toShortIO bs)
487482
toShortIO :: ByteString -> IO ShortByteString
488483
toShortIO (BS fptr len) = do
489484
mba <- stToIO (newByteArray len)
490-
let ptr = unsafeForeignPtrToPtr fptr
491-
stToIO (copyAddrToByteArray ptr mba 0 len)
492-
touchForeignPtr fptr
485+
BS.unsafeWithForeignPtr fptr $ \ptr ->
486+
stToIO (copyAddrToByteArray ptr mba 0 len)
493487
ShortByteString <$> stToIO (unsafeFreezeByteArray mba)
494488

495489
-- | /O(n)/. Convert a 'ShortByteString' into a 'ByteString'.
496490
--
497491
fromShort :: ShortByteString -> ByteString
498-
fromShort (unSBS -> b#)
499-
| isPinned b# = BS fp len
500-
where
501-
addr# = byteArrayContents# b#
502-
fp = ForeignPtr addr# (PlainPtr (unsafeCoerce# b#))
503-
len = I# (sizeofByteArray# b#)
504-
fromShort !sbs = unsafeDupablePerformIO (fromShortIO sbs)
505-
506-
fromShortIO :: ShortByteString -> IO ByteString
507-
fromShortIO sbs = do
508-
let len = length sbs
509-
mba@(MutableByteArray mba#) <- stToIO (newPinnedByteArray len)
510-
stToIO (copyByteArray (asBA sbs) 0 mba 0 len)
511-
let fp = ForeignPtr (byteArrayContents# (unsafeCoerce# mba#))
512-
(PlainPtr mba#)
513-
return (BS fp len)
492+
fromShort sbs@(unSBS -> b#)
493+
| isPinned b# = BS inPlaceFp len
494+
| otherwise = BS.unsafeCreateFp len $ \fp ->
495+
BS.unsafeWithForeignPtr fp $ \p -> copyToPtr sbs 0 p len
496+
where
497+
inPlaceFp = ForeignPtr (byteArrayContents# b#)
498+
(PlainPtr (unsafeCoerce# b#))
499+
len = I# (sizeofByteArray# b#)
514500

515501
-- | /O(1)/ Convert a 'Word8' into a 'ShortByteString'
516502
--
@@ -1614,12 +1600,6 @@ newByteArray len@(I# len#) =
16141600
ST $ \s -> case newByteArray# len# s of
16151601
(# s', mba# #) -> (# s', MutableByteArray mba# #)
16161602

1617-
newPinnedByteArray :: Int -> ST s (MutableByteArray s)
1618-
newPinnedByteArray len@(I# len#) =
1619-
assert (len >= 0) $
1620-
ST $ \s -> case newPinnedByteArray# len# s of
1621-
(# s', mba# #) -> (# s', MutableByteArray mba# #)
1622-
16231603
unsafeFreezeByteArray :: MutableByteArray s -> ST s ByteArray
16241604
unsafeFreezeByteArray (MutableByteArray mba#) =
16251605
ST $ \s -> case unsafeFreezeByteArray# mba# s of

0 commit comments

Comments
 (0)