Remove CPDF_Stream dependence from JBig2_BitStream.cpp.

Introduces safer span<> in the process. The uint32_t indexing
is still safe despite the size_t size(), since we reject spans
over a fixed limit.

Change-Id: Id8dd2116c27eb584b4007d8a35c11296bdab8b5a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/55330
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/jbig2/JBig2_BitStream.cpp b/core/fxcodec/jbig2/JBig2_BitStream.cpp
index a72099d..83c12d5 100644
--- a/core/fxcodec/jbig2/JBig2_BitStream.cpp
+++ b/core/fxcodec/jbig2/JBig2_BitStream.cpp
@@ -8,19 +8,11 @@
 
 #include <algorithm>
 
-#include "core/fpdfapi/parser/cpdf_stream.h"
-#include "core/fpdfapi/parser/cpdf_stream_acc.h"
-
-CJBig2_BitStream::CJBig2_BitStream(const RetainPtr<CPDF_StreamAcc>& pSrcStream)
-    : m_pBuf(pSrcStream->GetData()),
-      m_dwLength(pSrcStream->GetSize()),
-      m_dwByteIdx(0),
-      m_dwBitIdx(0),
-      m_dwObjNum(pSrcStream->GetStream() ? pSrcStream->GetStream()->GetObjNum()
-                                         : 0) {
-  if (m_dwLength > 256 * 1024 * 1024) {
-    m_dwLength = 0;
-    m_pBuf = nullptr;
+CJBig2_BitStream::CJBig2_BitStream(pdfium::span<const uint8_t> pSrcStream,
+                                   uint32_t dwObjNum)
+    : m_Span(pSrcStream), m_dwObjNum(dwObjNum) {
+  if (m_Span.size() > 256 * 1024 * 1024) {
+    m_Span = {};
   }
 }
 
@@ -42,7 +34,7 @@
 
   for (; dwBitPos > 0; --dwBitPos) {
     *dwResult =
-        (*dwResult << 1) | ((m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
+        (*dwResult << 1) | ((m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
     AdvanceBit();
   }
   return 0;
@@ -64,7 +56,7 @@
 
   for (; dwBitPos > 0; --dwBitPos) {
     *nResult =
-        (*nResult << 1) | ((m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
+        (*nResult << 1) | ((m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
     AdvanceBit();
   }
   return 0;
@@ -74,7 +66,7 @@
   if (!IsInBounds())
     return -1;
 
-  *dwResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
+  *dwResult = (m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
   AdvanceBit();
   return 0;
 }
@@ -83,7 +75,7 @@
   if (!IsInBounds())
     return -1;
 
-  *bResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
+  *bResult = (m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
   AdvanceBit();
   return 0;
 }
@@ -92,26 +84,26 @@
   if (!IsInBounds())
     return -1;
 
-  *cResult = m_pBuf[m_dwByteIdx];
+  *cResult = m_Span[m_dwByteIdx];
   ++m_dwByteIdx;
   return 0;
 }
 
 int32_t CJBig2_BitStream::readInteger(uint32_t* dwResult) {
-  if (m_dwByteIdx + 3 >= m_dwLength)
+  if (m_dwByteIdx + 3 >= m_Span.size())
     return -1;
 
-  *dwResult = (m_pBuf[m_dwByteIdx] << 24) | (m_pBuf[m_dwByteIdx + 1] << 16) |
-              (m_pBuf[m_dwByteIdx + 2] << 8) | m_pBuf[m_dwByteIdx + 3];
+  *dwResult = (m_Span[m_dwByteIdx] << 24) | (m_Span[m_dwByteIdx + 1] << 16) |
+              (m_Span[m_dwByteIdx + 2] << 8) | m_Span[m_dwByteIdx + 3];
   m_dwByteIdx += 4;
   return 0;
 }
 
 int32_t CJBig2_BitStream::readShortInteger(uint16_t* dwResult) {
-  if (m_dwByteIdx + 1 >= m_dwLength)
+  if (m_dwByteIdx + 1 >= m_Span.size())
     return -1;
 
-  *dwResult = (m_pBuf[m_dwByteIdx] << 8) | m_pBuf[m_dwByteIdx + 1];
+  *dwResult = (m_Span[m_dwByteIdx] << 8) | m_Span[m_dwByteIdx + 1];
   m_dwByteIdx += 2;
   return 0;
 }
@@ -124,7 +116,7 @@
 }
 
 uint8_t CJBig2_BitStream::getCurByte() const {
-  return IsInBounds() ? m_pBuf[m_dwByteIdx] : 0;
+  return IsInBounds() ? m_Span[m_dwByteIdx] : 0;
 }
 
 void CJBig2_BitStream::incByteIdx() {
@@ -133,11 +125,11 @@
 }
 
 uint8_t CJBig2_BitStream::getCurByte_arith() const {
-  return IsInBounds() ? m_pBuf[m_dwByteIdx] : 0xFF;
+  return IsInBounds() ? m_Span[m_dwByteIdx] : 0xFF;
 }
 
 uint8_t CJBig2_BitStream::getNextByte_arith() const {
-  return m_dwByteIdx + 1 < m_dwLength ? m_pBuf[m_dwByteIdx + 1] : 0xFF;
+  return m_dwByteIdx + 1 < m_Span.size() ? m_Span[m_dwByteIdx + 1] : 0xFF;
 }
 
 uint32_t CJBig2_BitStream::getOffset() const {
@@ -145,7 +137,7 @@
 }
 
 void CJBig2_BitStream::setOffset(uint32_t dwOffset) {
-  m_dwByteIdx = std::min(dwOffset, m_dwLength);
+  m_dwByteIdx = std::min<size_t>(dwOffset, m_Span.size());
 }
 
 uint32_t CJBig2_BitStream::getBitPos() const {
@@ -158,11 +150,11 @@
 }
 
 const uint8_t* CJBig2_BitStream::getBuf() const {
-  return m_pBuf;
+  return m_Span.data();
 }
 
 const uint8_t* CJBig2_BitStream::getPointer() const {
-  return m_pBuf + m_dwByteIdx;
+  return getBuf() + m_dwByteIdx;
 }
 
 void CJBig2_BitStream::offset(uint32_t dwOffset) {
@@ -170,7 +162,7 @@
 }
 
 uint32_t CJBig2_BitStream::getByteLeft() const {
-  return m_dwLength - m_dwByteIdx;
+  return m_Span.size() - m_dwByteIdx;
 }
 
 void CJBig2_BitStream::AdvanceBit() {
@@ -183,11 +175,11 @@
 }
 
 bool CJBig2_BitStream::IsInBounds() const {
-  return m_dwByteIdx < m_dwLength;
+  return m_dwByteIdx < m_Span.size();
 }
 
 uint32_t CJBig2_BitStream::LengthInBits() const {
-  return m_dwLength << 3;
+  return m_Span.size() << 3;
 }
 
 uint32_t CJBig2_BitStream::getObjNum() const {
diff --git a/core/fxcodec/jbig2/JBig2_BitStream.h b/core/fxcodec/jbig2/JBig2_BitStream.h
index 0edb432..e4bb82b 100644
--- a/core/fxcodec/jbig2/JBig2_BitStream.h
+++ b/core/fxcodec/jbig2/JBig2_BitStream.h
@@ -8,12 +8,11 @@
 #define CORE_FXCODEC_JBIG2_JBIG2_BITSTREAM_H_
 
 #include "core/fxcrt/retain_ptr.h"
-
-class CPDF_StreamAcc;
+#include "third_party/base/span.h"
 
 class CJBig2_BitStream {
  public:
-  explicit CJBig2_BitStream(const RetainPtr<CPDF_StreamAcc>& pSrcStream);
+  CJBig2_BitStream(pdfium::span<const uint8_t> pSrcStream, uint32_t dwObjNum);
   ~CJBig2_BitStream();
 
   // TODO(thestig): readFoo() should return bool.
@@ -34,22 +33,20 @@
   uint32_t getBitPos() const;
   void setBitPos(uint32_t dwBitPos);
   const uint8_t* getBuf() const;
-  uint32_t getLength() const { return m_dwLength; }
+  uint32_t getLength() const { return m_Span.size(); }
   const uint8_t* getPointer() const;
   void offset(uint32_t dwOffset);
   uint32_t getByteLeft() const;
   uint32_t getObjNum() const;
-
   bool IsInBounds() const;
 
  private:
   void AdvanceBit();
   uint32_t LengthInBits() const;
 
-  const uint8_t* m_pBuf;
-  uint32_t m_dwLength;
-  uint32_t m_dwByteIdx;
-  uint32_t m_dwBitIdx;
+  pdfium::span<const uint8_t> m_Span;
+  uint32_t m_dwByteIdx = 0;
+  uint32_t m_dwBitIdx = 0;
   const uint32_t m_dwObjNum;
 
   CJBig2_BitStream(const CJBig2_BitStream&) = delete;
diff --git a/core/fxcodec/jbig2/JBig2_BitStream_unittest.cpp b/core/fxcodec/jbig2/JBig2_BitStream_unittest.cpp
index 2dc6ca3..0e9ead5 100644
--- a/core/fxcodec/jbig2/JBig2_BitStream_unittest.cpp
+++ b/core/fxcodec/jbig2/JBig2_BitStream_unittest.cpp
@@ -21,7 +21,7 @@
   auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.Get());
   acc->LoadAllDataFiltered();
 
-  CJBig2_BitStream stream(acc);
+  CJBig2_BitStream stream(acc->GetSpan(), in_stream->GetObjNum());
 
   uint32_t val1;
   EXPECT_EQ(0, stream.readNBits(1, &val1));
@@ -46,7 +46,7 @@
   auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.Get());
   acc->LoadAllDataFiltered();
 
-  CJBig2_BitStream stream(acc);
+  CJBig2_BitStream stream(acc->GetSpan(), in_stream->GetObjNum());
 
   uint32_t val1;
   EXPECT_EQ(0, stream.readNBits(10, &val1));
@@ -58,7 +58,7 @@
   auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.Get());
   acc->LoadAllDataFiltered();
 
-  CJBig2_BitStream stream(acc);
+  CJBig2_BitStream stream(acc->GetSpan(), in_stream->GetObjNum());
 
   uint32_t val1;
   EXPECT_EQ(-1, stream.readNBits(1, &val1));
@@ -74,7 +74,7 @@
   auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.Get());
   acc->LoadAllDataFiltered();
 
-  CJBig2_BitStream stream(acc);
+  CJBig2_BitStream stream(acc->GetSpan(), in_stream->GetObjNum());
 
   uint32_t val1;
   EXPECT_EQ(-1, stream.readNBits(1, &val1));
@@ -91,7 +91,7 @@
   auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.Get());
   acc->LoadAllDataFiltered();
 
-  CJBig2_BitStream stream(acc);
+  CJBig2_BitStream stream(acc->GetSpan(), in_stream->GetObjNum());
 
   uint32_t val1;
   EXPECT_EQ(0, stream.readNBits(8, &val1));
@@ -112,7 +112,7 @@
   auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.Get());
   acc->LoadAllDataFiltered();
 
-  CJBig2_BitStream stream(acc);
+  CJBig2_BitStream stream(acc->GetSpan(), in_stream->GetObjNum());
 
   // This will shift off the top two bits and they end up lost.
   uint32_t val1;
diff --git a/core/fxcodec/jbig2/JBig2_Context.cpp b/core/fxcodec/jbig2/JBig2_Context.cpp
index 392d138..d2c243c 100644
--- a/core/fxcodec/jbig2/JBig2_Context.cpp
+++ b/core/fxcodec/jbig2/JBig2_Context.cpp
@@ -55,7 +55,9 @@
                                const RetainPtr<CPDF_StreamAcc>& pSrcStream,
                                std::list<CJBig2_CachePair>* pSymbolDictCache,
                                bool bIsGlobal)
-    : m_pStream(pdfium::MakeUnique<CJBig2_BitStream>(pSrcStream)),
+    : m_pStream(pdfium::MakeUnique<CJBig2_BitStream>(
+          pSrcStream->GetSpan(),
+          pSrcStream->GetStream() ? pSrcStream->GetStream()->GetObjNum() : 0)),
       m_HuffmanTables(CJBig2_HuffmanTable::kNumHuffmanTables),
       m_bInPage(false),
       m_bBufSpecified(false),