From 29d447ae35101675a2a2d8bc1dcfca65de7f3929 Mon Sep 17 00:00:00 2001 From: thestig Date: Thu, 23 Jun 2016 19:57:45 -0700 Subject: Improve hint table validation checks. Check required hint table dictionary entries and make sure they: - Exist. - Are of the right type. Along the way: - Fix FX_atonum() to not have a non-const pass-by-ref param. - Simplify code in CPDF_StreamContentParser. - Make CPDF_Number::IsInteger() a const method. BUG=610555 Review-Url: https://codereview.chromium.org/2095763003 --- core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp | 41 ++++++++++++++++++---------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp') diff --git a/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp b/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp index 5a7a7be544..cc5b529b45 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp @@ -6,6 +6,8 @@ #include "core/fpdfapi/fpdf_parser/include/cpdf_data_avail.h" +#include + #include "core/fpdfapi/fpdf_parser/cpdf_hint_tables.h" #include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" @@ -723,37 +725,48 @@ FX_BOOL CPDF_DataAvail::CheckHintTables(DownloadHints* pHints) { return FALSE; } - if (!pDict->KeyExist("H") || !pDict->KeyExist("O") || !pDict->KeyExist("N")) { + // The actual value is not required here, but validate its existence and type. + CPDF_Number* pFirstPage = ToNumber(pDict->GetDirectObjectBy("O")); + if (!pFirstPage || !pFirstPage->IsInteger()) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + + CPDF_Number* pPageCount = ToNumber(pDict->GetDirectObjectBy("N")); + if (!pPageCount || !pPageCount->IsInteger()) { m_docStatus = PDF_DATAAVAIL_ERROR; return FALSE; } - int nPageCount = pDict->GetDirectObjectBy("N")->GetInteger(); + int nPageCount = pPageCount->GetInteger(); if (nPageCount <= 1) { m_docStatus = PDF_DATAAVAIL_DONE; return TRUE; } CPDF_Array* pHintStreamRange = pDict->GetArrayBy("H"); - if (!pHintStreamRange) { + size_t nHintStreamSize = pHintStreamRange ? pHintStreamRange->GetCount() : 0; + if (nHintStreamSize != 2 && nHintStreamSize != 4) { m_docStatus = PDF_DATAAVAIL_ERROR; return FALSE; } - FX_FILESIZE szHSStart = - pHintStreamRange->GetDirectObjectAt(0) - ? pHintStreamRange->GetDirectObjectAt(0)->GetInteger() - : 0; - FX_FILESIZE szHSLength = - pHintStreamRange->GetDirectObjectAt(1) - ? pHintStreamRange->GetDirectObjectAt(1)->GetInteger() - : 0; - if (szHSStart < 0 || szHSLength <= 0) { + for (const CPDF_Object* pArrayObject : *pHintStreamRange) { + const CPDF_Number* pNumber = ToNumber(pArrayObject->GetDirect()); + if (!pNumber || !pNumber->IsInteger()) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + } + + FX_FILESIZE szHintStart = pHintStreamRange->GetIntegerAt(0); + FX_FILESIZE szHintLength = pHintStreamRange->GetIntegerAt(1); + if (szHintStart < 0 || szHintLength <= 0) { m_docStatus = PDF_DATAAVAIL_ERROR; return FALSE; } - if (!IsDataAvail(szHSStart, szHSLength, pHints)) + if (!IsDataAvail(szHintStart, szHintLength, pHints)) return FALSE; m_syntaxParser.InitParser(m_pFileRead, m_dwHeaderOffset); @@ -761,7 +774,7 @@ FX_BOOL CPDF_DataAvail::CheckHintTables(DownloadHints* pHints) { std::unique_ptr pHintTables( new CPDF_HintTables(this, pDict)); std::unique_ptr> pHintStream( - ParseIndirectObjectAt(szHSStart, 0)); + ParseIndirectObjectAt(szHintStart, 0)); CPDF_Stream* pStream = ToStream(pHintStream.get()); if (pStream && pHintTables->LoadHintStream(pStream)) m_pHintTables = std::move(pHintTables); -- cgit v1.2.3