summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/BitfieldMan.cc4
-rw-r--r--test/BitfieldManTest.cc22
2 files changed, 24 insertions, 2 deletions
diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc
index b0f202d4..e3c033f9 100644
--- a/src/BitfieldMan.cc
+++ b/src/BitfieldMan.cc
@@ -863,7 +863,7 @@ int64_t BitfieldMan::getOffsetCompletedLength
}
} else {
if(isBitSet(start)) {
- res += (start+1)*blockLength_-offset;
+ res += static_cast<int64_t>(start+1)*blockLength_-offset;
}
for(size_t i = start+1; i <= end-1; ++i) {
if(isBitSet(i)) {
@@ -871,7 +871,7 @@ int64_t BitfieldMan::getOffsetCompletedLength
}
}
if(isBitSet(end)) {
- res += offset+length-end*blockLength_;
+ res += offset+length-static_cast<int64_t>(end)*blockLength_;
}
}
return res;
diff --git a/test/BitfieldManTest.cc b/test/BitfieldManTest.cc
index de1fce4b..709a028a 100644
--- a/test/BitfieldManTest.cc
+++ b/test/BitfieldManTest.cc
@@ -28,6 +28,7 @@ class BitfieldManTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testGetSparseMissingUnusedIndex_withMinSplitSize);
CPPUNIT_TEST(testIsBitSetOffsetRange);
CPPUNIT_TEST(testGetOffsetCompletedLength);
+ CPPUNIT_TEST(testGetOffsetCompletedLength_largeFile);
CPPUNIT_TEST(testGetMissingUnusedLength);
CPPUNIT_TEST(testSetBitRange);
CPPUNIT_TEST(testGetAllMissingIndexes);
@@ -62,6 +63,7 @@ public:
void testGetSparseMissingUnusedIndex_withMinSplitSize();
void testIsBitSetOffsetRange();
void testGetOffsetCompletedLength();
+ void testGetOffsetCompletedLength_largeFile();
void testGetMissingUnusedLength();
void testSetBitRange();
void testCountFilteredBlock();
@@ -484,6 +486,26 @@ void BitfieldManTest::testGetOffsetCompletedLength()
CPPUNIT_ASSERT_EQUAL((int64_t)0, bt.getOffsetCompletedLength(1024*20, 1));
}
+void BitfieldManTest::testGetOffsetCompletedLength_largeFile()
+{
+ // Test for overflow on 32-bit systems.
+
+ // Total 4TiB, 4MiB block
+ BitfieldMan bt(1 << 22, 1LL << 40);
+ bt.setBit(1 << 11);
+ bt.setBit((1 << 11)+1);
+ bt.setBit((1 << 11)+2);
+
+ // The last piece is missing:
+ CPPUNIT_ASSERT_EQUAL((int64_t)bt.getBlockLength()*3,
+ bt.getOffsetCompletedLength(1LL << 33, 1 << 24));
+
+ // The first piece is missing:
+ CPPUNIT_ASSERT_EQUAL((int64_t)bt.getBlockLength()*3,
+ bt.getOffsetCompletedLength
+ ((1LL << 33) - bt.getBlockLength(), 1 << 24));
+}
+
void BitfieldManTest::testGetMissingUnusedLength()
{
int64_t totalLength = 1024*10+10;