Index: core/fpdfapi/parser/cpdf_data_avail.cpp |
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp |
index c4ed95e17f27d344afdede77d2c756d91a43aa35..e6d2c61ad384dbc4c3d104882648d6c9299cbc29 100644 |
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp |
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp |
@@ -15,6 +15,7 @@ |
#include "core/fpdfapi/parser/cpdf_dictionary.h" |
#include "core/fpdfapi/parser/cpdf_document.h" |
#include "core/fpdfapi/parser/cpdf_hint_tables.h" |
+#include "core/fpdfapi/parser/cpdf_linearized.h" |
#include "core/fpdfapi/parser/cpdf_name.h" |
#include "core/fpdfapi/parser/cpdf_number.h" |
#include "core/fpdfapi/parser/cpdf_reference.h" |
@@ -43,7 +44,6 @@ CPDF_DataAvail::CPDF_DataAvail(FileAvail* pFileAvail, |
m_dwCurrentOffset = 0; |
m_dwXRefOffset = 0; |
m_bufferOffset = 0; |
- m_dwFirstPageNo = 0; |
m_bufferSize = 0; |
m_PagesObjNum = 0; |
m_dwCurrentXRefSteam = 0; |
@@ -56,7 +56,6 @@ CPDF_DataAvail::CPDF_DataAvail(FileAvail* pFileAvail, |
m_bDocAvail = false; |
m_bMainXRefLoadTried = false; |
m_bDocAvail = false; |
- m_bLinearized = false; |
m_bPagesLoad = false; |
m_bPagesTreeLoad = false; |
m_bMainXRefLoadedOK = false; |
@@ -66,7 +65,6 @@ CPDF_DataAvail::CPDF_DataAvail(FileAvail* pFileAvail, |
m_bPageLoadedOK = false; |
m_bNeedDownLoadResource = false; |
m_bLinearizedFormParamLoad = false; |
- m_pLinearized = nullptr; |
m_pRoot = nullptr; |
m_pTrailer = nullptr; |
m_pCurrentParser = nullptr; |
@@ -83,9 +81,6 @@ CPDF_DataAvail::CPDF_DataAvail(FileAvail* pFileAvail, |
CPDF_DataAvail::~CPDF_DataAvail() { |
m_pHintTables.reset(); |
- delete m_pLinearized; |
- delete m_pRoot; |
- delete m_pTrailer; |
for (CPDF_Object* pObject : m_arrayAcroforms) |
delete pObject; |
@@ -613,48 +608,27 @@ bool CPDF_DataAvail::CheckHeader(DownloadHints* pHints) { |
} |
bool CPDF_DataAvail::CheckFirstPage(DownloadHints* pHints) { |
- CPDF_Dictionary* pDict = m_pLinearized->GetDict(); |
- CPDF_Object* pEndOffSet = pDict ? pDict->GetObjectFor("E") : nullptr; |
- if (!pEndOffSet) { |
- m_docStatus = PDF_DATAAVAIL_ERROR; |
- return false; |
- } |
- |
- CPDF_Object* pXRefOffset = pDict ? pDict->GetObjectFor("T") : nullptr; |
- if (!pXRefOffset) { |
- m_docStatus = PDF_DATAAVAIL_ERROR; |
- return false; |
- } |
- |
- CPDF_Object* pFileLen = pDict ? pDict->GetObjectFor("L") : nullptr; |
- if (!pFileLen) { |
+ if (!m_pLinearized->GetFirstPageEndOffset() || |
+ !m_pLinearized->GetFileSize() || !m_pLinearized->GetLastXRefOffset()) { |
m_docStatus = PDF_DATAAVAIL_ERROR; |
return false; |
} |
bool bNeedDownLoad = false; |
- if (pEndOffSet->IsNumber()) { |
- uint32_t dwEnd = pEndOffSet->GetInteger(); |
- dwEnd += 512; |
- if ((FX_FILESIZE)dwEnd > m_dwFileLen) |
- dwEnd = (uint32_t)m_dwFileLen; |
- |
- int32_t iStartPos = (int32_t)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen); |
- int32_t iSize = dwEnd > 1024 ? dwEnd - 1024 : 0; |
- if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) { |
- pHints->AddSegment(iStartPos, iSize); |
- bNeedDownLoad = true; |
- } |
- } |
+ uint32_t dwEnd = m_pLinearized->GetFirstPageEndOffset(); |
+ dwEnd += 512; |
+ if ((FX_FILESIZE)dwEnd > m_dwFileLen) |
+ dwEnd = (uint32_t)m_dwFileLen; |
- m_dwLastXRefOffset = 0; |
- FX_FILESIZE dwFileLen = 0; |
- if (pXRefOffset->IsNumber()) |
- m_dwLastXRefOffset = pXRefOffset->GetInteger(); |
- |
- if (pFileLen->IsNumber()) |
- dwFileLen = pFileLen->GetInteger(); |
+ int32_t iStartPos = (int32_t)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen); |
+ int32_t iSize = dwEnd > 1024 ? dwEnd - 1024 : 0; |
+ if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) { |
+ pHints->AddSegment(iStartPos, iSize); |
+ bNeedDownLoad = true; |
+ } |
+ m_dwLastXRefOffset = m_pLinearized->GetLastXRefOffset(); |
+ FX_FILESIZE dwFileLen = m_pLinearized->GetFileSize(); |
if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, |
(uint32_t)(dwFileLen - m_dwLastXRefOffset))) { |
if (m_docStatus == PDF_DATAAVAIL_FIRSTPAGE) { |
@@ -702,52 +676,17 @@ bool CPDF_DataAvail::IsDataAvail(FX_FILESIZE offset, |
} |
bool CPDF_DataAvail::CheckHintTables(DownloadHints* pHints) { |
- CPDF_Dictionary* pDict = m_pLinearized->GetDict(); |
- if (!pDict) { |
- m_docStatus = PDF_DATAAVAIL_ERROR; |
- return false; |
- } |
- |
- // The actual value is not required here, but validate its existence and type. |
- CPDF_Number* pFirstPage = ToNumber(pDict->GetDirectObjectFor("O")); |
- if (!pFirstPage || !pFirstPage->IsInteger()) { |
- m_docStatus = PDF_DATAAVAIL_ERROR; |
- return false; |
- } |
- |
- CPDF_Number* pPageCount = ToNumber(pDict->GetDirectObjectFor("N")); |
- if (!pPageCount || !pPageCount->IsInteger()) { |
- m_docStatus = PDF_DATAAVAIL_ERROR; |
- return false; |
- } |
- |
- int nPageCount = pPageCount->GetInteger(); |
- if (nPageCount <= 1) { |
+ if (m_pLinearized->GetPageCount() <= 1) { |
m_docStatus = PDF_DATAAVAIL_DONE; |
return true; |
} |
- |
- CPDF_Array* pHintStreamRange = pDict->GetArrayFor("H"); |
- size_t nHintStreamSize = pHintStreamRange ? pHintStreamRange->GetCount() : 0; |
- if (nHintStreamSize != 2 && nHintStreamSize != 4) { |
+ if (!m_pLinearized->HasHintTable()) { |
m_docStatus = PDF_DATAAVAIL_ERROR; |
return false; |
} |
- 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; |
- } |
+ FX_FILESIZE szHintStart = m_pLinearized->GetHintStart(); |
+ FX_FILESIZE szHintLength = m_pLinearized->GetHintLength(); |
if (!IsDataAvail(szHintStart, szHintLength, pHints)) |
return false; |
@@ -755,7 +694,7 @@ bool CPDF_DataAvail::CheckHintTables(DownloadHints* pHints) { |
m_syntaxParser.InitParser(m_pFileRead, m_dwHeaderOffset); |
std::unique_ptr<CPDF_HintTables> pHintTables( |
- new CPDF_HintTables(this, pDict)); |
+ new CPDF_HintTables(this, m_pLinearized.get())); |
std::unique_ptr<CPDF_Object> pHintStream( |
ParseIndirectObjectAt(szHintStart, 0)); |
CPDF_Stream* pStream = ToStream(pHintStream.get()); |
@@ -819,12 +758,12 @@ CPDF_DataAvail::DocLinearizationStatus CPDF_DataAvail::IsLinearizedPDF() { |
} |
bool CPDF_DataAvail::IsLinearized() { |
- return m_bLinearized; |
+ return !!m_pLinearized; |
} |
bool CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, uint32_t dwLen) { |
if (m_pLinearized) |
- return m_bLinearized; |
+ return true; |
ScopedFileStream file(FX_CreateMemoryStream(pData, (size_t)dwLen, false)); |
@@ -844,27 +783,13 @@ bool CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, uint32_t dwLen) { |
return false; |
uint32_t objnum = FXSYS_atoui(wordObjNum.c_str()); |
- m_pLinearized = |
- ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum); |
- if (!m_pLinearized) |
- return false; |
- |
- CPDF_Dictionary* pDict = m_pLinearized->GetDict(); |
- if (!pDict || !pDict->GetObjectFor("Linearized")) |
+ m_pLinearized = CPDF_Linearized::CreateForObject(pdfium::WrapUnique( |
+ ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum))); |
+ if (!m_pLinearized || |
+ m_pLinearized->GetFileSize() != m_pFileRead->GetSize()) { |
+ m_pLinearized.reset(); |
return false; |
- |
- CPDF_Object* pLen = pDict->GetObjectFor("L"); |
- if (!pLen) |
- return false; |
- |
- if ((FX_FILESIZE)pLen->GetInteger() != m_pFileRead->GetSize()) |
- return false; |
- |
- m_bLinearized = true; |
- |
- if (CPDF_Number* pNo = ToNumber(pDict->GetObjectFor("P"))) |
- m_dwFirstPageNo = pNo->GetInteger(); |
- |
+ } |
return true; |
} |
@@ -1600,8 +1525,8 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail( |
if (pdfium::ContainsKey(m_pagesLoadState, dwPage)) |
return DataAvailable; |
- if (m_bLinearized) { |
- if (dwPage == m_dwFirstPageNo) { |
+ if (m_pLinearized) { |
+ if (dwPage == m_pLinearized->GetFirstPageNo()) { |
DocAvailStatus nRet = CheckLinearizedFirstPage(dwPage, pHints); |
if (nRet == DataAvailable) |
m_pagesLoadState.insert(dwPage); |
@@ -1731,11 +1656,8 @@ void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, |
} |
int CPDF_DataAvail::GetPageCount() const { |
- if (m_pLinearized) { |
- CPDF_Dictionary* pDict = m_pLinearized->GetDict(); |
- CPDF_Object* pObj = pDict ? pDict->GetDirectObjectFor("N") : nullptr; |
- return pObj ? pObj->GetInteger() : 0; |
- } |
+ if (m_pLinearized) |
+ return m_pLinearized->GetPageCount(); |
return m_pDocument ? m_pDocument->GetPageCount() : 0; |
} |
@@ -1748,10 +1670,7 @@ CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) { |
if (!m_pLinearized || !m_pHintTables) |
return nullptr; |
- CPDF_Dictionary* pDict = m_pLinearized->GetDict(); |
- CPDF_Object* pObj = pDict ? pDict->GetDirectObjectFor("P") : nullptr; |
- int firstPageNum = pObj ? pObj->GetInteger() : 0; |
- if (index == firstPageNum) |
+ if (index == static_cast<int>(m_pLinearized->GetFirstPageNo())) |
return nullptr; |
FX_FILESIZE szPageStartPos = 0; |
FX_FILESIZE szPageLength = 0; |