diff options
-rw-r--r-- | src/System/Torrent/Storage.hs | 20 | ||||
-rw-r--r-- | tests/System/Torrent/StorageSpec.hs | 8 |
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 | ||
97 | writePiece :: Piece BL.ByteString -> Storage -> IO () | 97 | writePiece :: Piece BL.ByteString -> Storage -> IO () |
98 | writePiece p @ Piece {..} s @ Storage {..} | 98 | writePiece 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 | ||
106 | readPiece :: PieceIx -> Storage -> IO (Piece BL.ByteString) | 118 | readPiece :: 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" $ |