From ccd5be05f61c85754daf5c8155f4932f6d35a55a Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Wed, 30 Aug 2017 13:23:44 -0400 Subject: Move CFX_BitStream to its own file This CL moves the CFX_BitStream code out of fx_basic and into cfx_bitstream. Bug: pdfium:867 Change-Id: I5b7e6190a7db1fe1d24feb6bd676035a5c73ee92 Reviewed-on: https://pdfium-review.googlesource.com/12350 Commit-Queue: dsinclair Reviewed-by: Tom Sepez --- BUILD.gn | 2 ++ core/fpdfapi/page/cpdf_meshstream.cpp | 37 ++++++++++--------- core/fpdfapi/page/cpdf_meshstream.h | 6 ++-- core/fpdfapi/parser/cpdf_hint_tables.cpp | 4 +-- core/fpdfapi/parser/cpdf_hint_tables.h | 1 - core/fxcrt/cfx_bitstream.cpp | 57 ++++++++++++++++++++++++++++++ core/fxcrt/cfx_bitstream.h | 38 ++++++++++++++++++++ core/fxcrt/fx_basic.h | 20 ----------- core/fxcrt/fx_basic_buffer.cpp | 44 ----------------------- testing/libfuzzer/pdf_hint_table_fuzzer.cc | 4 +-- 10 files changed, 122 insertions(+), 91 deletions(-) create mode 100644 core/fxcrt/cfx_bitstream.cpp create mode 100644 core/fxcrt/cfx_bitstream.h diff --git a/BUILD.gn b/BUILD.gn index 1a08382bf6..969c917924 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -803,6 +803,8 @@ config("fxge_warnings") { static_library("fxcrt") { sources = [ + "core/fxcrt/cfx_bitstream.cpp", + "core/fxcrt/cfx_bitstream.h", "core/fxcrt/cfx_bytestring.cpp", "core/fxcrt/cfx_bytestring.h", "core/fxcrt/cfx_datetime.cpp", diff --git a/core/fpdfapi/page/cpdf_meshstream.cpp b/core/fpdfapi/page/cpdf_meshstream.cpp index 8588734d95..1850efde9c 100644 --- a/core/fpdfapi/page/cpdf_meshstream.cpp +++ b/core/fpdfapi/page/cpdf_meshstream.cpp @@ -117,7 +117,8 @@ CPDF_MeshStream::~CPDF_MeshStream() {} bool CPDF_MeshStream::Load() { m_pStream->LoadAllData(); - m_BitStream.Init(m_pStream->GetData(), m_pStream->GetSize()); + m_BitStream = pdfium::MakeUnique(m_pStream->GetData(), + m_pStream->GetSize()); CPDF_Dictionary* pDict = m_pShadingStream->GetDict(); m_nCoordBits = pDict->GetIntegerFor("BitsPerCoordinate"); m_nComponentBits = pDict->GetIntegerFor("BitsPerComponent"); @@ -158,20 +159,20 @@ bool CPDF_MeshStream::Load() { } bool CPDF_MeshStream::CanReadFlag() const { - return m_BitStream.BitsRemaining() >= m_nFlagBits; + return m_BitStream->BitsRemaining() >= m_nFlagBits; } bool CPDF_MeshStream::CanReadCoords() const { - return m_BitStream.BitsRemaining() / 2 >= m_nCoordBits; + return m_BitStream->BitsRemaining() / 2 >= m_nCoordBits; } bool CPDF_MeshStream::CanReadColor() const { - return m_BitStream.BitsRemaining() / m_nComponentBits >= m_nComponents; + return m_BitStream->BitsRemaining() / m_nComponentBits >= m_nComponents; } uint32_t CPDF_MeshStream::ReadFlag() { ASSERT(ShouldCheckBitsPerFlag(m_type)); - return m_BitStream.GetBits(m_nFlagBits) & 0x03; + return m_BitStream->GetBits(m_nFlagBits) & 0x03; } CFX_PointF CPDF_MeshStream::ReadCoords() { @@ -179,17 +180,15 @@ CFX_PointF CPDF_MeshStream::ReadCoords() { CFX_PointF pos; if (m_nCoordBits == 32) { - pos.x = m_xmin + - m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / - static_cast(m_CoordMax); - pos.y = m_ymin + - m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / - static_cast(m_CoordMax); + pos.x = m_xmin + m_BitStream->GetBits(m_nCoordBits) * (m_xmax - m_xmin) / + static_cast(m_CoordMax); + pos.y = m_ymin + m_BitStream->GetBits(m_nCoordBits) * (m_ymax - m_ymin) / + static_cast(m_CoordMax); } else { pos.x = m_xmin + - m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax; + m_BitStream->GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax; pos.y = m_ymin + - m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax; + m_BitStream->GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax; } return pos; } @@ -199,9 +198,9 @@ std::tuple CPDF_MeshStream::ReadColor() { float color_value[kMaxComponents]; for (uint32_t i = 0; i < m_nComponents; ++i) { - color_value[i] = m_ColorMin[i] + - m_BitStream.GetBits(m_nComponentBits) * - (m_ColorMax[i] - m_ColorMin[i]) / m_ComponentMax; + color_value[i] = m_ColorMin[i] + m_BitStream->GetBits(m_nComponentBits) * + (m_ColorMax[i] - m_ColorMin[i]) / + m_ComponentMax; } float r = 0.0; @@ -238,7 +237,7 @@ bool CPDF_MeshStream::ReadVertex(const CFX_Matrix& pObject2Bitmap, if (!CanReadColor()) return false; std::tie(vertex->r, vertex->g, vertex->b) = ReadColor(); - m_BitStream.ByteAlign(); + m_BitStream->ByteAlign(); return true; } @@ -247,7 +246,7 @@ std::vector CPDF_MeshStream::ReadVertexRow( int count) { std::vector vertices; for (int i = 0; i < count; ++i) { - if (m_BitStream.IsEOF() || !CanReadCoords()) + if (m_BitStream->IsEOF() || !CanReadCoords()) return std::vector(); vertices.push_back(CPDF_MeshVertex()); @@ -257,7 +256,7 @@ std::vector CPDF_MeshStream::ReadVertexRow( return std::vector(); std::tie(vertex.r, vertex.g, vertex.b) = ReadColor(); - m_BitStream.ByteAlign(); + m_BitStream->ByteAlign(); } return vertices; } diff --git a/core/fpdfapi/page/cpdf_meshstream.h b/core/fpdfapi/page/cpdf_meshstream.h index 60c47790a4..0a06381c68 100644 --- a/core/fpdfapi/page/cpdf_meshstream.h +++ b/core/fpdfapi/page/cpdf_meshstream.h @@ -13,7 +13,7 @@ #include "core/fpdfapi/page/cpdf_shadingpattern.h" #include "core/fpdfapi/parser/cpdf_stream_acc.h" -#include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/cfx_bitstream.h" #include "core/fxcrt/fx_system.h" class CPDF_MeshVertex { @@ -57,7 +57,7 @@ class CPDF_MeshStream { std::vector ReadVertexRow(const CFX_Matrix& pObject2Bitmap, int count); - CFX_BitStream* BitStream() { return &m_BitStream; } + CFX_BitStream* BitStream() { return m_BitStream.get(); } uint32_t ComponentBits() const { return m_nComponentBits; } uint32_t Components() const { return m_nComponents; } @@ -81,7 +81,7 @@ class CPDF_MeshStream { float m_ColorMin[kMaxComponents]; float m_ColorMax[kMaxComponents]; CFX_RetainPtr m_pStream; - CFX_BitStream m_BitStream; + std::unique_ptr m_BitStream; }; #endif // CORE_FPDFAPI_PAGE_CPDF_MESHSTREAM_H_ diff --git a/core/fpdfapi/parser/cpdf_hint_tables.cpp b/core/fpdfapi/parser/cpdf_hint_tables.cpp index 6a84143f9e..deffe5cb38 100644 --- a/core/fpdfapi/parser/cpdf_hint_tables.cpp +++ b/core/fpdfapi/parser/cpdf_hint_tables.cpp @@ -15,6 +15,7 @@ #include "core/fpdfapi/parser/cpdf_linearized_header.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/cpdf_stream_acc.h" +#include "core/fxcrt/cfx_bitstream.h" #include "core/fxcrt/fx_safe_types.h" #include "third_party/base/numerics/safe_conversions.h" @@ -486,8 +487,7 @@ bool CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { return false; } - CFX_BitStream bs; - bs.Init(pAcc->GetData(), size); + CFX_BitStream bs(pAcc->GetData(), size); return ReadPageHintTable(&bs) && ReadSharedObjHintTable(&bs, shared_hint_table_offset); } diff --git a/core/fpdfapi/parser/cpdf_hint_tables.h b/core/fpdfapi/parser/cpdf_hint_tables.h index 25f276ce55..2ab42a93cf 100644 --- a/core/fpdfapi/parser/cpdf_hint_tables.h +++ b/core/fpdfapi/parser/cpdf_hint_tables.h @@ -11,7 +11,6 @@ #include "core/fpdfapi/parser/cpdf_data_avail.h" #include "core/fxcrt/cfx_unowned_ptr.h" -#include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_stream.h" class CFX_BitStream; diff --git a/core/fxcrt/cfx_bitstream.cpp b/core/fxcrt/cfx_bitstream.cpp new file mode 100644 index 0000000000..7cf6d36adf --- /dev/null +++ b/core/fxcrt/cfx_bitstream.cpp @@ -0,0 +1,57 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fxcrt/cfx_bitstream.h" + +#include + +#include "core/fxcrt/fx_system.h" + +CFX_BitStream::CFX_BitStream(const uint8_t* pData, uint32_t dwSize) + : m_BitPos(0), m_BitSize(dwSize * 8), m_pData(pData) { + ASSERT(dwSize <= std::numeric_limits::max() / 8); +} + +CFX_BitStream::~CFX_BitStream() {} + +void CFX_BitStream::ByteAlign() { + m_BitPos = (m_BitPos + 7) & ~7; +} + +uint32_t CFX_BitStream::GetBits(uint32_t nBits) { + if (nBits > m_BitSize || m_BitPos + nBits > m_BitSize) + return 0; + + const uint8_t* data = m_pData.Get(); + + if (nBits == 1) { + int bit = (data[m_BitPos / 8] & (1 << (7 - m_BitPos % 8))) ? 1 : 0; + m_BitPos++; + return bit; + } + + uint32_t byte_pos = m_BitPos / 8; + uint32_t bit_pos = m_BitPos % 8; + uint32_t bit_left = nBits; + uint32_t result = 0; + if (bit_pos) { + if (8 - bit_pos >= bit_left) { + result = (data[byte_pos] & (0xff >> bit_pos)) >> (8 - bit_pos - bit_left); + m_BitPos += bit_left; + return result; + } + bit_left -= 8 - bit_pos; + result = (data[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left; + } + while (bit_left >= 8) { + bit_left -= 8; + result |= data[byte_pos++] << bit_left; + } + if (bit_left) + result |= data[byte_pos] >> (8 - bit_left); + m_BitPos += nBits; + return result; +} diff --git a/core/fxcrt/cfx_bitstream.h b/core/fxcrt/cfx_bitstream.h new file mode 100644 index 0000000000..1829f23b92 --- /dev/null +++ b/core/fxcrt/cfx_bitstream.h @@ -0,0 +1,38 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FXCRT_CFX_BITSTREAM_H_ +#define CORE_FXCRT_CFX_BITSTREAM_H_ + +#include + +#include "core/fxcrt/cfx_unowned_ptr.h" + +class CFX_BitStream { + public: + CFX_BitStream(const uint8_t* pData, uint32_t dwSize); + ~CFX_BitStream(); + + void ByteAlign(); + + bool IsEOF() const { return m_BitPos >= m_BitSize; } + uint32_t GetPos() const { return m_BitPos; } + uint32_t GetBits(uint32_t nBits); + + void SkipBits(uint32_t nBits) { m_BitPos += nBits; } + void Rewind() { m_BitPos = 0; } + + uint32_t BitsRemaining() const { + return m_BitSize >= m_BitPos ? m_BitSize - m_BitPos : 0; + } + + private: + uint32_t m_BitPos; + uint32_t m_BitSize; + CFX_UnownedPtr m_pData; +}; + +#endif // CORE_FXCRT_CFX_BITSTREAM_H_ diff --git a/core/fxcrt/fx_basic.h b/core/fxcrt/fx_basic.h index 1f05dfb627..167ef5ce70 100644 --- a/core/fxcrt/fx_basic.h +++ b/core/fxcrt/fx_basic.h @@ -136,26 +136,6 @@ class CFX_FixedBufGrow { std::unique_ptr m_pGrowData; }; -class CFX_BitStream { - public: - void Init(const uint8_t* pData, uint32_t dwSize); - - void ByteAlign(); - bool IsEOF() const { return m_BitPos >= m_BitSize; } - uint32_t GetBits(uint32_t nBits); - void SkipBits(uint32_t nBits) { m_BitPos += nBits; } - void Rewind() { m_BitPos = 0; } - uint32_t GetPos() const { return m_BitPos; } - uint32_t BitsRemaining() const { - return m_BitSize >= m_BitPos ? m_BitSize - m_BitPos : 0; - } - - private: - uint32_t m_BitPos; - uint32_t m_BitSize; - const uint8_t* m_pData; -}; - class IFX_Pause { public: virtual ~IFX_Pause() {} diff --git a/core/fxcrt/fx_basic_buffer.cpp b/core/fxcrt/fx_basic_buffer.cpp index 310aec7faf..b93c1bc9da 100644 --- a/core/fxcrt/fx_basic_buffer.cpp +++ b/core/fxcrt/fx_basic_buffer.cpp @@ -145,47 +145,3 @@ CFX_WideTextBuf& CFX_WideTextBuf::operator<<(const CFX_WideTextBuf& buf) { AppendBlock(buf.m_pBuffer.get(), buf.m_DataSize); return *this; } - -void CFX_BitStream::Init(const uint8_t* pData, uint32_t dwSize) { - m_pData = pData; - m_BitSize = dwSize * 8; - m_BitPos = 0; -} - -void CFX_BitStream::ByteAlign() { - m_BitPos = (m_BitPos + 7) & ~7; -} - -uint32_t CFX_BitStream::GetBits(uint32_t nBits) { - if (nBits > m_BitSize || m_BitPos + nBits > m_BitSize) - return 0; - - if (nBits == 1) { - int bit = (m_pData[m_BitPos / 8] & (1 << (7 - m_BitPos % 8))) ? 1 : 0; - m_BitPos++; - return bit; - } - - uint32_t byte_pos = m_BitPos / 8; - uint32_t bit_pos = m_BitPos % 8; - uint32_t bit_left = nBits; - uint32_t result = 0; - if (bit_pos) { - if (8 - bit_pos >= bit_left) { - result = - (m_pData[byte_pos] & (0xff >> bit_pos)) >> (8 - bit_pos - bit_left); - m_BitPos += bit_left; - return result; - } - bit_left -= 8 - bit_pos; - result = (m_pData[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left; - } - while (bit_left >= 8) { - bit_left -= 8; - result |= m_pData[byte_pos++] << bit_left; - } - if (bit_left) - result |= m_pData[byte_pos] >> (8 - bit_left); - m_BitPos += nBits; - return result; -} diff --git a/testing/libfuzzer/pdf_hint_table_fuzzer.cc b/testing/libfuzzer/pdf_hint_table_fuzzer.cc index b31d56eb8f..ac4229a5a9 100644 --- a/testing/libfuzzer/pdf_hint_table_fuzzer.cc +++ b/testing/libfuzzer/pdf_hint_table_fuzzer.cc @@ -10,6 +10,7 @@ #include "core/fpdfapi/parser/cpdf_hint_tables.h" #include "core/fpdfapi/parser/cpdf_linearized_header.h" #include "core/fpdfapi/parser/cpdf_number.h" +#include "core/fxcrt/cfx_bitstream.h" #include "third_party/base/ptr_util.h" int32_t GetData(const int32_t** data32, const uint8_t** data, size_t* size) { @@ -35,8 +36,7 @@ class HintTableForFuzzing : public CPDF_HintTables { if (size < static_cast(shared_hint_table_offset_)) return; - CFX_BitStream bs; - bs.Init(data, size); + CFX_BitStream bs(data, size); if (!ReadPageHintTable(&bs)) return; ReadSharedObjHintTable(&bs, shared_hint_table_offset_); -- cgit v1.2.3