Use size_t for sizes in CFX_BitStream.
As would be flagged by -Wshorten-64-to-32
-- beef up some tests.
Change-Id: Iae5f29624ed47870e652eb09aa53debaf4503c78
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/86892
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcrt/cfx_bitstream.cpp b/core/fxcrt/cfx_bitstream.cpp
index 7b1e502..406552a 100644
--- a/core/fxcrt/cfx_bitstream.cpp
+++ b/core/fxcrt/cfx_bitstream.cpp
@@ -10,11 +10,11 @@
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_system.h"
-#include "third_party/base/check.h"
+#include "third_party/base/check_op.h"
CFX_BitStream::CFX_BitStream(pdfium::span<const uint8_t> pData)
: m_BitSize(pData.size() * 8), m_pData(pData.data()) {
- DCHECK(pData.size() <= std::numeric_limits<uint32_t>::max() / 8);
+ CHECK_LE(pData.size(), std::numeric_limits<size_t>::max() / 8);
}
CFX_BitStream::~CFX_BitStream() = default;
@@ -30,12 +30,12 @@
return 0;
const uint32_t bit_pos = m_BitPos % 8;
- uint32_t byte_pos = m_BitPos / 8;
+ size_t byte_pos = m_BitPos / 8;
const uint8_t* data = m_pData.Get();
uint8_t current_byte = data[byte_pos];
if (nBits == 1) {
- int bit = (current_byte & (1 << (7 - bit_pos))) ? 1 : 0;
+ uint32_t bit = (current_byte & (1 << (7 - bit_pos))) ? 1 : 0;
m_BitPos++;
return bit;
}
diff --git a/core/fxcrt/cfx_bitstream.h b/core/fxcrt/cfx_bitstream.h
index 731a637..1b3cdd8 100644
--- a/core/fxcrt/cfx_bitstream.h
+++ b/core/fxcrt/cfx_bitstream.h
@@ -7,6 +7,7 @@
#ifndef CORE_FXCRT_CFX_BITSTREAM_H_
#define CORE_FXCRT_CFX_BITSTREAM_H_
+#include <stddef.h>
#include <stdint.h>
#include "core/fxcrt/unowned_ptr.h"
@@ -20,19 +21,19 @@
void ByteAlign();
bool IsEOF() const { return m_BitPos >= m_BitSize; }
- uint32_t GetPos() const { return m_BitPos; }
+ size_t GetPos() const { return m_BitPos; }
uint32_t GetBits(uint32_t nBits);
- void SkipBits(uint32_t nBits) { m_BitPos += nBits; }
+ void SkipBits(size_t nBits) { m_BitPos += nBits; }
void Rewind() { m_BitPos = 0; }
- uint32_t BitsRemaining() const {
+ size_t BitsRemaining() const {
return m_BitSize >= m_BitPos ? m_BitSize - m_BitPos : 0;
}
private:
- uint32_t m_BitPos = 0;
- const uint32_t m_BitSize;
+ size_t m_BitPos = 0;
+ const size_t m_BitSize;
UnownedPtr<const uint8_t> const m_pData;
};
diff --git a/core/fxcrt/cfx_bitstream_unittest.cpp b/core/fxcrt/cfx_bitstream_unittest.cpp
index 2ba3663..35688c4 100644
--- a/core/fxcrt/cfx_bitstream_unittest.cpp
+++ b/core/fxcrt/cfx_bitstream_unittest.cpp
@@ -3,6 +3,9 @@
// found in the LICENSE file.
#include "core/fxcrt/cfx_bitstream.h"
+
+#include <limits>
+
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -116,6 +119,63 @@
EXPECT_TRUE(bitstream.IsEOF());
EXPECT_EQ(1063U, bitstream.GetPos());
EXPECT_EQ(0U, bitstream.BitsRemaining());
+ EXPECT_EQ(0u, bitstream.GetBits(4));
+
+ // Align past the end.
+ bitstream.ByteAlign();
+ EXPECT_TRUE(bitstream.IsEOF());
+ EXPECT_EQ(1064U, bitstream.GetPos());
+ EXPECT_EQ(0U, bitstream.BitsRemaining());
+ EXPECT_EQ(0u, bitstream.GetBits(4));
+}
+
+TEST(fxcrt, BitStreamEmpty) {
+ CFX_BitStream bitstream({});
+ EXPECT_TRUE(bitstream.IsEOF());
+ EXPECT_EQ(0U, bitstream.GetPos());
+ EXPECT_EQ(0U, bitstream.BitsRemaining());
+
+ // Getting bits returns zero and doesn't advance.
+ EXPECT_EQ(0u, bitstream.GetBits(4));
+ EXPECT_EQ(0U, bitstream.GetPos());
+
+ // Skip past the end.
+ bitstream.SkipBits(63);
+ EXPECT_TRUE(bitstream.IsEOF());
+ EXPECT_EQ(63U, bitstream.GetPos());
+ EXPECT_EQ(0U, bitstream.BitsRemaining());
+ EXPECT_EQ(0u, bitstream.GetBits(4));
+
+ // Align past the end.
+ bitstream.ByteAlign();
+ EXPECT_TRUE(bitstream.IsEOF());
+ EXPECT_EQ(64U, bitstream.GetPos());
+ EXPECT_EQ(0U, bitstream.BitsRemaining());
+ EXPECT_EQ(0u, bitstream.GetBits(4));
+}
+
+TEST(fxcrt, BitStreamBig) {
+ // We can't actually allocate enough memory to test the limits of
+ // the bitstream arithmetic, but as long as we don't try to extract
+ // any bits, the calculations should be unaffected.
+ constexpr size_t kAllocationBytes = std::numeric_limits<size_t>::max() / 8;
+ constexpr size_t kAllocationBits = kAllocationBytes * 8;
+ CFX_BitStream bitstream({nullptr, kAllocationBytes});
+ EXPECT_FALSE(bitstream.IsEOF());
+ EXPECT_EQ(0U, bitstream.GetPos());
+ EXPECT_EQ(kAllocationBits, bitstream.BitsRemaining());
+
+ // Skip some bits.
+ bitstream.SkipBits(kAllocationBits - 1023);
+ EXPECT_FALSE(bitstream.IsEOF());
+ EXPECT_EQ(kAllocationBits - 1023, bitstream.GetPos());
+ EXPECT_EQ(1023u, bitstream.BitsRemaining());
+
+ // Align to byte.
+ bitstream.ByteAlign();
+ EXPECT_FALSE(bitstream.IsEOF());
+ EXPECT_EQ(kAllocationBits - 1016, bitstream.GetPos());
+ EXPECT_EQ(1016u, bitstream.BitsRemaining());
}
TEST(fxcrt, BitStreamSameAsReferenceGetBits32) {