From acef5fe15d16868768989ba53639b7a7cad6fad3 Mon Sep 17 00:00:00 2001 From: thestig Date: Wed, 1 Jun 2016 13:45:03 -0700 Subject: Validate the BitsPerFlag entry in shading dictionaries. BUG=616248 Review-Url: https://codereview.chromium.org/2020183004 --- core/fpdfapi/fpdf_page/cpdf_meshstream.cpp | 42 +++++++++++++++++++++++++---- core/fpdfapi/fpdf_page/cpdf_meshstream.h | 19 ++++++++----- core/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 4 +-- 3 files changed, 51 insertions(+), 14 deletions(-) (limited to 'core/fpdfapi/fpdf_page') diff --git a/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp b/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp index de35541839..d3649a1fdc 100644 --- a/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp @@ -44,17 +44,46 @@ bool IsValidBitsPerCoordinate(uint32_t x) { } } +// See PDF Reference 1.7, page 315, table 4.32. (Also table 4.34) +bool ShouldCheckBitsPerFlag(ShadingType type) { + switch (type) { + case kFreeFormGouraudTriangleMeshShading: + case kCoonsPatchMeshShading: + case kTensorProductPatchMeshShading: + return true; + default: + return false; + } +} + +// Same references as ShouldCheckBitsPerFlag() above. +bool IsValidBitsPerFlag(uint32_t x) { + switch (x) { + case 2: + case 4: + case 8: + return true; + default: + return false; + } +} + } // namespace CPDF_MeshStream::CPDF_MeshStream( + ShadingType type, const std::vector>& funcs, + CPDF_Stream* pShadingStream, CPDF_ColorSpace* pCS) - : m_funcs(funcs), m_pCS(pCS) {} + : m_type(type), + m_funcs(funcs), + m_pShadingStream(pShadingStream), + m_pCS(pCS) {} -bool CPDF_MeshStream::Load(CPDF_Stream* pShadingStream) { - m_Stream.LoadAllData(pShadingStream); +bool CPDF_MeshStream::Load() { + m_Stream.LoadAllData(m_pShadingStream); m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize()); - CPDF_Dictionary* pDict = pShadingStream->GetDict(); + CPDF_Dictionary* pDict = m_pShadingStream->GetDict(); m_nCoordBits = pDict->GetIntegerBy("BitsPerCoordinate"); if (!IsValidBitsPerCoordinate(m_nCoordBits)) return false; @@ -64,6 +93,9 @@ bool CPDF_MeshStream::Load(CPDF_Stream* pShadingStream) { 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) return false; @@ -87,6 +119,7 @@ bool CPDF_MeshStream::Load(CPDF_Stream* pShadingStream) { } uint32_t CPDF_MeshStream::GetFlag() { + ASSERT(ShouldCheckBitsPerFlag(m_type)); return m_BitStream.GetBits(m_nFlagBits) & 0x03; } @@ -105,7 +138,6 @@ void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { } void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { - static const int kMaxResults = 8; FX_FLOAT color_value[kMaxResults]; for (uint32_t i = 0; i < m_nComps; ++i) { color_value[i] = m_ColorMin[i] + diff --git a/core/fpdfapi/fpdf_page/cpdf_meshstream.h b/core/fpdfapi/fpdf_page/cpdf_meshstream.h index e5d37fe36b..8f47265acd 100644 --- a/core/fpdfapi/fpdf_page/cpdf_meshstream.h +++ b/core/fpdfapi/fpdf_page/cpdf_meshstream.h @@ -10,6 +10,7 @@ #include #include +#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" #include "core/fxcrt/include/fx_basic.h" #include "core/fxcrt/include/fx_system.h" @@ -29,12 +30,14 @@ class CPDF_Stream; class CPDF_MeshStream { public: - CPDF_MeshStream(const std::vector>& funcs, + CPDF_MeshStream(ShadingType type, + const std::vector>& funcs, + CPDF_Stream* pShadingStream, CPDF_ColorSpace* pCS); - bool Load(CPDF_Stream* pShadingStream); - uint32_t GetFlag(); + bool Load(); + uint32_t GetFlag(); void GetCoords(FX_FLOAT& x, FX_FLOAT& y); void GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b); @@ -44,13 +47,15 @@ class CPDF_MeshStream { CFX_Matrix* pObject2Bitmap); CFX_BitStream* BitStream() { return &m_BitStream; } - uint32_t CoordBits() const { return m_nCoordBits; } uint32_t CompBits() const { return m_nCompBits; } - uint32_t FlagBits() const { return m_nFlagBits; } uint32_t comps() const { return m_nComps; } private: + static const uint32_t kMaxResults = 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; @@ -62,8 +67,8 @@ class CPDF_MeshStream { FX_FLOAT m_xmax; FX_FLOAT m_ymin; FX_FLOAT m_ymax; - FX_FLOAT m_ColorMin[8]; - FX_FLOAT m_ColorMax[8]; + FX_FLOAT m_ColorMin[kMaxResults]; + FX_FLOAT m_ColorMax[kMaxResults]; 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 ddea2e653d..0592c97176 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -106,8 +106,8 @@ CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading, if (!pStream || !pCS) return CFX_FloatRect(0, 0, 0, 0); - CPDF_MeshStream stream(pShading->GetFuncs(), pCS); - if (!stream.Load(pStream)) + CPDF_MeshStream stream(type, pShading->GetFuncs(), pStream, pCS); + if (!stream.Load()) return CFX_FloatRect(0, 0, 0, 0); CFX_FloatRect rect; -- cgit v1.2.3