summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/System/Torrent/Storage.hs20
-rw-r--r--tests/System/Torrent/StorageSpec.hs8
2 files changed, 22 insertions, 6 deletions
diff --git a/src/System/Torrent/Storage.hs b/src/System/Torrent/Storage.hs
index 3bb229a4..8aa1aa99 100644
--- a/src/System/Torrent/Storage.hs
+++ b/src/System/Torrent/Storage.hs
@@ -96,11 +96,23 @@ isValidIx i s = 0 <= i && i < totalPieces s
96 96
97writePiece :: Piece BL.ByteString -> Storage -> IO () 97writePiece :: Piece BL.ByteString -> Storage -> IO ()
98writePiece p @ Piece {..} s @ Storage {..} 98writePiece p @ Piece {..} s @ Storage {..}
99 | mode == ReadOnly = throwIO StorageIsRO 99 | mode == ReadOnly = throwIO StorageIsRO
100 | pieceSize p /= pieceLen = throwIO (InvalidSize (pieceSize p)) 100 | isNotValidIx pieceIndex = throwIO (InvalidIndex pieceIndex)
101 | not (isValidIx pieceIndex s) = throwIO (InvalidIndex pieceIndex) 101 | isNotValidSize pieceIndex (pieceSize p)
102 | otherwise = writeBytes offset pieceData fileMap 102 = throwIO (InvalidSize (pieceSize p))
103 | otherwise = writeBytes offset pieceData fileMap
103 where 104 where
105 isNotValidSize pix psize
106 | succ pix == pcount = psize /= lastPieceLen -- last piece may be shorter
107 | otherwise = psize /= pieceLen
108 where
109 lastPieceLen = fromIntegral (FM.size fileMap `rem` fromIntegral pieceLen)
110 {-# INLINE isNotValidSize #-}
111
112 isNotValidIx i = i < 0 || i >= pcount
113 {-# INLINE isNotValidIx #-}
114
115 pcount = totalPieces s
104 offset = fromIntegral pieceIndex * fromIntegral pieceLen 116 offset = fromIntegral pieceIndex * fromIntegral pieceLen
105 117
106readPiece :: PieceIx -> Storage -> IO (Piece BL.ByteString) 118readPiece :: PieceIx -> Storage -> IO (Piece BL.ByteString)
diff --git a/tests/System/Torrent/StorageSpec.hs b/tests/System/Torrent/StorageSpec.hs
index d2185961..2e94ccf1 100644
--- a/tests/System/Torrent/StorageSpec.hs
+++ b/tests/System/Torrent/StorageSpec.hs
@@ -52,8 +52,12 @@ spec = before createLayout $ do
52 it "should fail on out of upper bound index" $ do 52 it "should fail on out of upper bound index" $ do
53 withStorage ReadWrite 100 layout $ \ s -> do 53 withStorage ReadWrite 100 layout $ \ s -> do
54 let bs = BL.replicate 100 0 54 let bs = BL.replicate 100 0
55 writePiece (Piece 1 bs) s 55 writePiece (Piece 0 bs) s
56 writePiece (Piece 2 bs) s `shouldThrow` (== InvalidIndex 2) 56
57 let bs' = BL.replicate 75 0
58 writePiece (Piece 1 bs') s
59
60 writePiece (Piece 2 bs') s `shouldThrow` (== InvalidIndex 2)
57 61
58 describe "readPiece" $ do 62 describe "readPiece" $ do
59 it "should fail on negative index" $ 63 it "should fail on negative index" $