From 8590a98297c5a56e63efc63931c1b3998160e049 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Fri, 21 Sep 2018 15:34:45 +0000 Subject: Validate more image values in CPDF_DIBBase. Change-Id: Ia5f72e6397ee959d897a945c4069f47c494b5511 Reviewed-on: https://pdfium-review.googlesource.com/42870 Commit-Queue: Ryan Harrison Reviewed-by: Ryan Harrison --- core/fpdfapi/page/cpdf_image.cpp | 10 ++++------ core/fpdfapi/page/cpdf_image.h | 3 +++ core/fpdfapi/render/cpdf_dibbase.cpp | 30 +++++++++++++++++++++++++----- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp index 85e7d8a038..f7eec131ad 100644 --- a/core/fpdfapi/page/cpdf_image.cpp +++ b/core/fpdfapi/page/cpdf_image.cpp @@ -32,18 +32,16 @@ #include "third_party/base/numerics/safe_conversions.h" #include "third_party/base/ptr_util.h" -namespace { - -bool IsValidJpegComponent(int32_t comps) { +// static +bool CPDF_Image::IsValidJpegComponent(int32_t comps) { return comps == 1 || comps == 3 || comps == 4; } -bool IsValidJpegBitsPerComponent(int32_t bpc) { +// static +bool CPDF_Image::IsValidJpegBitsPerComponent(int32_t bpc) { return bpc == 1 || bpc == 2 || bpc == 4 || bpc == 8 || bpc == 16; } -} // namespace - CPDF_Image::CPDF_Image(CPDF_Document* pDoc) : m_pDocument(pDoc) {} CPDF_Image::CPDF_Image(CPDF_Document* pDoc, diff --git a/core/fpdfapi/page/cpdf_image.h b/core/fpdfapi/page/cpdf_image.h index f7752213f1..b4636711fd 100644 --- a/core/fpdfapi/page/cpdf_image.h +++ b/core/fpdfapi/page/cpdf_image.h @@ -28,6 +28,9 @@ class CPDF_Image final : public Retainable { template friend RetainPtr pdfium::MakeRetain(Args&&... args); + static bool IsValidJpegComponent(int32_t comps); + static bool IsValidJpegBitsPerComponent(int32_t bpc); + void ConvertStreamToIndirectObject(); CPDF_Dictionary* GetDict() const; diff --git a/core/fpdfapi/render/cpdf_dibbase.cpp b/core/fpdfapi/render/cpdf_dibbase.cpp index d342a99ae0..3557672e81 100644 --- a/core/fpdfapi/render/cpdf_dibbase.cpp +++ b/core/fpdfapi/render/cpdf_dibbase.cpp @@ -54,7 +54,12 @@ bool GetBitValue(const uint8_t* pSrc, uint32_t pos) { return pSrc[pos / 8] & (1 << (7 - pos % 8)); } -bool IsAllowedBPCValue(int bpc) { +// Just to sanity check and filter out obvious bad values. +bool IsMaybeValidBitsPerComponent(int bpc) { + return bpc >= 0 && bpc <= 16; +} + +bool IsAllowedBitsPerComponent(int bpc) { return bpc == 1 || bpc == 2 || bpc == 4 || bpc == 8 || bpc == 16; } @@ -338,6 +343,9 @@ CPDF_DIBBase::LoadState CPDF_DIBBase::ContinueLoadDIBBase( bool CPDF_DIBBase::LoadColorInfo(const CPDF_Dictionary* pFormResources, const CPDF_Dictionary* pPageResources) { m_bpc_orig = m_pDict->GetIntegerFor("BitsPerComponent"); + if (!IsMaybeValidBitsPerComponent(m_bpc_orig)) + return false; + if (m_pDict->GetIntegerFor("ImageMask")) m_bImageMask = true; @@ -517,6 +525,10 @@ bool CPDF_DIBBase::CreateDCTDecoder(pdfium::span src_span, &bTransform)) { return false; } + if (!CPDF_Image::IsValidJpegComponent(comps) || + !CPDF_Image::IsValidJpegBitsPerComponent(bpc)) { + return false; + } if (m_nComponents == static_cast(comps)) { m_bpc = bpc; @@ -719,10 +731,18 @@ void CPDF_DIBBase::LoadPalette() { if (!m_pColorSpace || m_Family == PDFCS_PATTERN) return; - if (m_bpc == 0 || m_bpc * m_nComponents > 8) + if (m_bpc == 0) return; - if (m_bpc * m_nComponents == 1) { + // Use FX_SAFE_UINT32 just to be on the safe side, in case |m_bpc| or + // |m_nComponents| somehow gets a bad value. + FX_SAFE_UINT32 safe_bits = m_bpc; + safe_bits *= m_nComponents; + uint32_t bits = safe_bits.ValueOrDefault(255); + if (bits > 8) + return; + + if (bits == 1) { if (m_bDefaultDecode && (m_Family == PDFCS_DEVICEGRAY || m_Family == PDFCS_DEVICERGB)) { return; @@ -759,7 +779,7 @@ void CPDF_DIBBase::LoadPalette() { return; } - int palette_count = 1 << (m_bpc * m_nComponents); + int palette_count = 1 << bits; // Using at least 16 elements due to the call m_pColorSpace->GetRGB(). std::vector color_values(std::max(m_nComponents, 16u)); for (int i = 0; i < palette_count; i++) { @@ -817,7 +837,7 @@ void CPDF_DIBBase::ValidateDictParam() { } } - if (!IsAllowedBPCValue(m_bpc)) + if (!IsAllowedBitsPerComponent(m_bpc)) m_bpc = 0; } -- cgit v1.2.3