From c3246466df915a5b8a639dd3a611d18cd106773b Mon Sep 17 00:00:00 2001 From: thestig Date: Wed, 1 Jun 2016 13:49:04 -0700 Subject: Relax checks added in commit 8f3a311. Some shading types do not use these fields. Review-Url: https://codereview.chromium.org/2027053002 --- core/fpdfapi/fpdf_page/cpdf_meshstream.cpp | 74 +++++++++++++++++++++-------- core/fpdfapi/fpdf_page/cpdf_meshstream.h | 16 +++---- core/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 4 +- 3 files changed, 63 insertions(+), 31 deletions(-) diff --git a/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp b/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp index d3649a1fdc..1d9c56046a 100644 --- a/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp @@ -13,6 +13,19 @@ namespace { // See PDF Reference 1.7, page 315, table 4.32. (Also table 4.33 and 4.34) +bool ShouldCheckBPC(ShadingType type) { + switch (type) { + case kFreeFormGouraudTriangleMeshShading: + case kLatticeFormGouraudTriangleMeshShading: + case kCoonsPatchMeshShading: + case kTensorProductPatchMeshShading: + return true; + default: + return false; + } +} + +// Same references as ShouldCheckBPC() above. bool IsValidBitsPerComponent(uint32_t x) { switch (x) { case 1: @@ -27,7 +40,7 @@ bool IsValidBitsPerComponent(uint32_t x) { } } -// Same references as IsValidBitsPerComponent() above. +// Same references as ShouldCheckBPC() above. bool IsValidBitsPerCoordinate(uint32_t x) { switch (x) { case 1: @@ -78,43 +91,60 @@ CPDF_MeshStream::CPDF_MeshStream( : m_type(type), m_funcs(funcs), m_pShadingStream(pShadingStream), - m_pCS(pCS) {} + m_pCS(pCS), + m_nCoordBits(0), + m_nComponentBits(0), + m_nFlagBits(0), + m_nComponents(0), + m_CoordMax(0), + m_ComponentMax(0), + m_xmin(0), + m_xmax(0), + m_ymin(0), + m_ymax(0) { + memset(&m_ColorMin, 0, sizeof(m_ColorMin)); + memset(&m_ColorMax, 0, sizeof(m_ColorMax)); +} bool CPDF_MeshStream::Load() { m_Stream.LoadAllData(m_pShadingStream); m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize()); CPDF_Dictionary* pDict = m_pShadingStream->GetDict(); m_nCoordBits = pDict->GetIntegerBy("BitsPerCoordinate"); - if (!IsValidBitsPerCoordinate(m_nCoordBits)) - return false; - - m_nCompBits = pDict->GetIntegerBy("BitsPerComponent"); - if (!IsValidBitsPerComponent(m_nCompBits)) - return false; + m_nComponentBits = pDict->GetIntegerBy("BitsPerComponent"); + if (ShouldCheckBPC(m_type)) { + if (!IsValidBitsPerCoordinate(m_nCoordBits)) + return false; + if (!IsValidBitsPerComponent(m_nComponentBits)) + return false; + } m_nFlagBits = pDict->GetIntegerBy("BitsPerFlag"); if (ShouldCheckBitsPerFlag(m_type) && !IsValidBitsPerFlag(m_nFlagBits)) return false; - uint32_t nComps = m_pCS->CountComponents(); - if (nComps > 8) + uint32_t nComponents = m_pCS->CountComponents(); + if (nComponents > kMaxComponents) return false; - m_nComps = m_funcs.empty() ? nComps : 1; - m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1; - m_CompMax = (1 << m_nCompBits) - 1; + m_nComponents = m_funcs.empty() ? nComponents : 1; CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); - if (!pDecode || pDecode->GetCount() != 4 + m_nComps * 2) + if (!pDecode || pDecode->GetCount() != 4 + m_nComponents * 2) return false; m_xmin = pDecode->GetNumberAt(0); m_xmax = pDecode->GetNumberAt(1); m_ymin = pDecode->GetNumberAt(2); m_ymax = pDecode->GetNumberAt(3); - for (uint32_t i = 0; i < m_nComps; ++i) { + for (uint32_t i = 0; i < m_nComponents; ++i) { m_ColorMin[i] = pDecode->GetNumberAt(i * 2 + 4); m_ColorMax[i] = pDecode->GetNumberAt(i * 2 + 5); } + + if (ShouldCheckBPC(m_type)) { + m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1; + m_ComponentMax = (1 << m_nComponentBits) - 1; + } return true; } @@ -124,6 +154,7 @@ uint32_t CPDF_MeshStream::GetFlag() { } void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { + ASSERT(ShouldCheckBPC(m_type)); if (m_nCoordBits == 32) { x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / (double)m_CoordMax); @@ -138,22 +169,23 @@ void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { } void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { - FX_FLOAT color_value[kMaxResults]; - for (uint32_t i = 0; i < m_nComps; ++i) { + ASSERT(ShouldCheckBPC(m_type)); + FX_FLOAT color_value[kMaxComponents]; + for (uint32_t i = 0; i < m_nComponents; ++i) { color_value[i] = m_ColorMin[i] + - m_BitStream.GetBits(m_nCompBits) * - (m_ColorMax[i] - m_ColorMin[i]) / m_CompMax; + m_BitStream.GetBits(m_nComponentBits) * + (m_ColorMax[i] - m_ColorMin[i]) / m_ComponentMax; } if (m_funcs.empty()) { m_pCS->GetRGB(color_value, r, g, b); return; } - FX_FLOAT result[kMaxResults]; + FX_FLOAT result[kMaxComponents]; FXSYS_memset(result, 0, sizeof(result)); int nResults; for (const auto& func : m_funcs) { - if (func && func->CountOutputs() <= kMaxResults) + if (func && func->CountOutputs() <= kMaxComponents) func->Call(color_value, 1, result, nResults); } m_pCS->GetRGB(result, r, g, b); diff --git a/core/fpdfapi/fpdf_page/cpdf_meshstream.h b/core/fpdfapi/fpdf_page/cpdf_meshstream.h index 8f47265acd..b8a8c38f37 100644 --- a/core/fpdfapi/fpdf_page/cpdf_meshstream.h +++ b/core/fpdfapi/fpdf_page/cpdf_meshstream.h @@ -47,28 +47,28 @@ class CPDF_MeshStream { CFX_Matrix* pObject2Bitmap); CFX_BitStream* BitStream() { return &m_BitStream; } - uint32_t CompBits() const { return m_nCompBits; } - uint32_t comps() const { return m_nComps; } + uint32_t ComponentBits() const { return m_nComponentBits; } + uint32_t Components() const { return m_nComponents; } private: - static const uint32_t kMaxResults = 8; + static const uint32_t kMaxComponents = 8; const ShadingType m_type; const std::vector>& m_funcs; CPDF_Stream* const m_pShadingStream; CPDF_ColorSpace* const m_pCS; uint32_t m_nCoordBits; - uint32_t m_nCompBits; + uint32_t m_nComponentBits; uint32_t m_nFlagBits; - uint32_t m_nComps; + uint32_t m_nComponents; uint32_t m_CoordMax; - uint32_t m_CompMax; + uint32_t m_ComponentMax; FX_FLOAT m_xmin; FX_FLOAT m_xmax; FX_FLOAT m_ymin; FX_FLOAT m_ymax; - FX_FLOAT m_ColorMin[kMaxResults]; - FX_FLOAT m_ColorMax[kMaxResults]; + FX_FLOAT m_ColorMin[kMaxComponents]; + FX_FLOAT m_ColorMax[kMaxComponents]; CPDF_StreamAcc m_Stream; CFX_BitStream m_BitStream; }; diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp index 0592c97176..52576043e3 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -146,8 +146,8 @@ CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading, bStarted = true; } } - FX_SAFE_UINT32 nBits = stream.comps(); - nBits *= stream.CompBits(); + FX_SAFE_UINT32 nBits = stream.Components(); + nBits *= stream.ComponentBits(); nBits *= color_count; if (!nBits.IsValid()) break; -- cgit v1.2.3