Chromium Code Reviews| Index: 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 5a7a7be544f34bdcfeec83ad1524a4ddf5805b4e..cc5b529b4555f67fc425d10d2fb7c03282063a4a 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 <algorithm> |
| + |
| #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) { |
|
dsinclair
2016/06/23 23:35:25
Where does the 4 come from?
Lei Zhang
2016/06/24 00:37:43
PDF 1.7 spec, page 1029, Table F.1.
|
| 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<CPDF_HintTables> pHintTables( |
| new CPDF_HintTables(this, pDict)); |
| std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pHintStream( |
| - ParseIndirectObjectAt(szHSStart, 0)); |
| + ParseIndirectObjectAt(szHintStart, 0)); |
| CPDF_Stream* pStream = ToStream(pHintStream.get()); |
| if (pStream && pHintTables->LoadHintStream(pStream)) |
| m_pHintTables = std::move(pHintTables); |