summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/parser/cpdf_data_avail.cpp369
1 files changed, 189 insertions, 180 deletions
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index 64eaf2a43b..40134a021a 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -135,7 +135,8 @@ bool CPDF_DataAvail::AreObjectsAvailable(std::vector<CPDF_Object*>& obj_array,
CPDF_Array* pArray = pObj->AsArray();
for (size_t k = 0; k < pArray->GetCount(); ++k)
new_obj_array.push_back(pArray->GetObjectAt(k));
- } break;
+ break;
+ }
case CPDF_Object::STREAM:
pObj = pObj->GetDict();
case CPDF_Object::DICTIONARY: {
@@ -147,7 +148,8 @@ bool CPDF_DataAvail::AreObjectsAvailable(std::vector<CPDF_Object*>& obj_array,
if (it.first != "Parent")
new_obj_array.push_back(it.second.get());
}
- } break;
+ break;
+ }
case CPDF_Object::REFERENCE: {
CPDF_Reference* pRef = pObj->AsReference();
uint32_t dwNum = pRef->GetRefObjNum();
@@ -167,7 +169,8 @@ bool CPDF_DataAvail::AreObjectsAvailable(std::vector<CPDF_Object*>& obj_array,
if (pReferred)
new_obj_array.push_back(pReferred);
}
- } break;
+ break;
+ }
}
}
@@ -522,7 +525,8 @@ bool CPDF_DataAvail::GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages) {
if (CPDF_Reference* pRef = ToReference(pKidsArray->GetObjectAt(i)))
m_PageObjList.push_back(pRef->GetRefObjNum());
}
- } break;
+ break;
+ }
default:
m_docStatus = PDF_DATAAVAIL_ERROR;
return false;
@@ -560,22 +564,21 @@ bool CPDF_DataAvail::CheckHeader(DownloadHints* pHints) {
ASSERT(m_dwFileLen >= 0);
const uint32_t kReqSize = std::min(static_cast<uint32_t>(m_dwFileLen), 1024U);
- if (m_pFileAvail->IsDataAvail(0, kReqSize)) {
- uint8_t buffer[1024];
- m_pFileRead->ReadBlock(buffer, 0, kReqSize);
-
- if (IsLinearizedFile(buffer, kReqSize)) {
- m_docStatus = PDF_DATAAVAIL_FIRSTPAGE;
- } else {
- if (m_docStatus == PDF_DATAAVAIL_ERROR)
- return false;
- m_docStatus = PDF_DATAAVAIL_END;
- }
- return true;
+ if (!m_pFileAvail->IsDataAvail(0, kReqSize)) {
+ pHints->AddSegment(0, kReqSize);
+ return false;
}
- pHints->AddSegment(0, kReqSize);
- return false;
+ uint8_t buffer[1024];
+ m_pFileRead->ReadBlock(buffer, 0, kReqSize);
+ if (IsLinearizedFile(buffer, kReqSize)) {
+ m_docStatus = PDF_DATAAVAIL_FIRSTPAGE;
+ } else {
+ if (m_docStatus == PDF_DATAAVAIL_ERROR)
+ return false;
+ m_docStatus = PDF_DATAAVAIL_END;
+ }
+ return true;
}
bool CPDF_DataAvail::CheckFirstPage(DownloadHints* pHints) {
@@ -746,43 +749,43 @@ bool CPDF_DataAvail::CheckEnd(DownloadHints* pHints) {
uint32_t req_pos = (uint32_t)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0);
uint32_t dwSize = (uint32_t)(m_dwFileLen - req_pos);
- if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) {
- uint8_t buffer[1024];
- m_pFileRead->ReadBlock(buffer, req_pos, dwSize);
+ if (!m_pFileAvail->IsDataAvail(req_pos, dwSize)) {
+ pHints->AddSegment(req_pos, dwSize);
+ return false;
+ }
- CFX_RetainPtr<IFX_MemoryStream> file =
- IFX_MemoryStream::Create(buffer, (size_t)dwSize, false);
- m_syntaxParser.InitParser(file, 0);
- m_syntaxParser.RestorePos(dwSize - 1);
+ uint8_t buffer[1024];
+ m_pFileRead->ReadBlock(buffer, req_pos, dwSize);
- if (m_syntaxParser.SearchWord("startxref", true, false, dwSize)) {
- m_syntaxParser.GetNextWord(nullptr);
+ CFX_RetainPtr<IFX_MemoryStream> file =
+ IFX_MemoryStream::Create(buffer, (size_t)dwSize, false);
+ m_syntaxParser.InitParser(file, 0);
+ m_syntaxParser.RestorePos(dwSize - 1);
- bool bNumber;
- CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(&bNumber);
- if (!bNumber) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return false;
- }
+ if (!m_syntaxParser.SearchWord("startxref", true, false, dwSize)) {
+ m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
+ return true;
+ }
- m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str.c_str());
- if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return true;
- }
+ m_syntaxParser.GetNextWord(nullptr);
- m_dwLastXRefOffset = m_dwXRefOffset;
- SetStartOffset(m_dwXRefOffset);
- m_docStatus = PDF_DATAAVAIL_CROSSREF;
- return true;
- }
+ bool bNumber;
+ CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(&bNumber);
+ if (!bNumber) {
+ m_docStatus = PDF_DATAAVAIL_ERROR;
+ return false;
+ }
+ m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str.c_str());
+ if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) {
m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
return true;
}
- pHints->AddSegment(req_pos, dwSize);
- return false;
+ m_dwLastXRefOffset = m_dwXRefOffset;
+ SetStartOffset(m_dwXRefOffset);
+ m_docStatus = PDF_DATAAVAIL_CROSSREF;
+ return true;
}
int32_t CPDF_DataAvail::CheckCrossRefStream(DownloadHints* pHints,
@@ -791,42 +794,43 @@ int32_t CPDF_DataAvail::CheckCrossRefStream(DownloadHints* pHints,
uint32_t req_size =
(uint32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
- if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) {
- int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam);
- CFX_BinaryBuf buf(iSize);
- uint8_t* pBuf = buf.GetBuffer();
+ if (!m_pFileAvail->IsDataAvail(m_Pos, req_size)) {
+ pHints->AddSegment(m_Pos, req_size);
+ return 0;
+ }
- m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize);
+ int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam);
+ CFX_BinaryBuf buf(iSize);
+ uint8_t* pBuf = buf.GetBuffer();
- CFX_RetainPtr<IFX_MemoryStream> file =
- IFX_MemoryStream::Create(pBuf, (size_t)iSize, false);
- m_parser.m_pSyntax->InitParser(file, 0);
+ m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize);
- bool bNumber;
- CFX_ByteString objnum = m_parser.m_pSyntax->GetNextWord(&bNumber);
- if (!bNumber)
- return -1;
+ CFX_RetainPtr<IFX_MemoryStream> file =
+ IFX_MemoryStream::Create(pBuf, (size_t)iSize, false);
+ m_parser.m_pSyntax->InitParser(file, 0);
- uint32_t objNum = FXSYS_atoui(objnum.c_str());
- std::unique_ptr<CPDF_Object> pObj =
- m_parser.ParseIndirectObjectAt(nullptr, 0, objNum);
+ bool bNumber;
+ CFX_ByteString objnum = m_parser.m_pSyntax->GetNextWord(&bNumber);
+ if (!bNumber)
+ return -1;
- if (!pObj) {
- m_Pos += m_parser.m_pSyntax->SavePos();
- return 0;
- }
+ uint32_t objNum = FXSYS_atoui(objnum.c_str());
+ std::unique_ptr<CPDF_Object> pObj =
+ m_parser.ParseIndirectObjectAt(nullptr, 0, objNum);
- CPDF_Dictionary* pDict = pObj->GetDict();
- CPDF_Name* pName = ToName(pDict ? pDict->GetObjectFor("Type") : nullptr);
- if (pName && pName->GetString() == "XRef") {
- m_Pos += m_parser.m_pSyntax->SavePos();
- xref_offset = pObj->GetDict()->GetIntegerFor("Prev");
- return 1;
- }
- return -1;
+ if (!pObj) {
+ m_Pos += m_parser.m_pSyntax->SavePos();
+ return 0;
}
- pHints->AddSegment(m_Pos, req_size);
- return 0;
+
+ CPDF_Dictionary* pDict = pObj->GetDict();
+ CPDF_Name* pName = ToName(pDict ? pDict->GetObjectFor("Type") : nullptr);
+ if (pName && pName->GetString() == "XRef") {
+ m_Pos += m_parser.m_pSyntax->SavePos();
+ xref_offset = pObj->GetDict()->GetIntegerFor("Prev");
+ return 1;
+ }
+ return -1;
}
void CPDF_DataAvail::SetStartOffset(FX_FILESIZE dwOffset) {
@@ -960,14 +964,13 @@ bool CPDF_DataAvail::CheckCrossRefItem(DownloadHints* pHints) {
bool CPDF_DataAvail::CheckAllCrossRefStream(DownloadHints* pHints) {
FX_FILESIZE xref_offset = 0;
-
int32_t nRet = CheckCrossRefStream(pHints, xref_offset);
if (nRet == 1) {
- if (!xref_offset) {
- m_docStatus = PDF_DATAAVAIL_LOADALLCROSSREF;
- } else {
+ if (xref_offset) {
m_dwCurrentXRefSteam = xref_offset;
m_Pos = xref_offset;
+ } else {
+ m_docStatus = PDF_DATAAVAIL_LOADALLCROSSREF;
}
return true;
}
@@ -986,26 +989,25 @@ bool CPDF_DataAvail::CheckCrossRef(DownloadHints* pHints) {
return false;
}
- if (token == "xref") {
- while (1) {
- if (!GetNextToken(token)) {
- iSize =
- (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
- pHints->AddSegment(m_Pos, iSize);
- m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM;
- return false;
- }
-
- if (token == "trailer") {
- m_dwTrailerOffset = m_Pos;
- m_docStatus = PDF_DATAAVAIL_TRAILER;
- return true;
- }
- }
- } else {
+ if (token != "xref") {
m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
return true;
}
+
+ while (1) {
+ if (!GetNextToken(token)) {
+ iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
+ pHints->AddSegment(m_Pos, iSize);
+ m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM;
+ return false;
+ }
+
+ if (token == "trailer") {
+ m_dwTrailerOffset = m_Pos;
+ m_docStatus = PDF_DATAAVAIL_TRAILER;
+ return true;
+ }
+ }
return false;
}
@@ -1033,62 +1035,65 @@ bool CPDF_DataAvail::CheckTrailerAppend(DownloadHints* pHints) {
bool CPDF_DataAvail::CheckTrailer(DownloadHints* pHints) {
int32_t iTrailerSize =
(int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
- if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) {
- int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset);
- CFX_BinaryBuf buf(iSize);
- uint8_t* pBuf = buf.GetBuffer();
- if (!pBuf) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return false;
- }
+ if (!m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) {
+ pHints->AddSegment(m_Pos, iTrailerSize);
+ return false;
+ }
- if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize))
- return false;
+ int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset);
+ CFX_BinaryBuf buf(iSize);
+ uint8_t* pBuf = buf.GetBuffer();
+ if (!pBuf) {
+ m_docStatus = PDF_DATAAVAIL_ERROR;
+ return false;
+ }
- CFX_RetainPtr<IFX_MemoryStream> file =
- IFX_MemoryStream::Create(pBuf, (size_t)iSize, false);
- m_syntaxParser.InitParser(file, 0);
+ if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize))
+ return false;
- std::unique_ptr<CPDF_Object> pTrailer(
- m_syntaxParser.GetObject(nullptr, 0, 0, true));
- if (!pTrailer) {
- m_Pos += m_syntaxParser.SavePos();
- pHints->AddSegment(m_Pos, iTrailerSize);
- return false;
- }
+ CFX_RetainPtr<IFX_MemoryStream> file =
+ IFX_MemoryStream::Create(pBuf, (size_t)iSize, false);
+ m_syntaxParser.InitParser(file, 0);
+
+ std::unique_ptr<CPDF_Object> pTrailer(
+ m_syntaxParser.GetObject(nullptr, 0, 0, true));
+ if (!pTrailer) {
+ m_Pos += m_syntaxParser.SavePos();
+ pHints->AddSegment(m_Pos, iTrailerSize);
+ return false;
+ }
- if (!pTrailer->IsDictionary())
- return false;
+ if (!pTrailer->IsDictionary())
+ return false;
- CPDF_Dictionary* pTrailerDict = pTrailer->GetDict();
- CPDF_Object* pEncrypt = pTrailerDict->GetObjectFor("Encrypt");
- if (ToReference(pEncrypt)) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return true;
- }
+ CPDF_Dictionary* pTrailerDict = pTrailer->GetDict();
+ CPDF_Object* pEncrypt = pTrailerDict->GetObjectFor("Encrypt");
+ if (ToReference(pEncrypt)) {
+ m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
+ return true;
+ }
- uint32_t xrefpos = GetDirectInteger(pTrailerDict, "Prev");
- if (xrefpos) {
- m_dwPrevXRefOffset = GetDirectInteger(pTrailerDict, "XRefStm");
- if (m_dwPrevXRefOffset) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- } else {
- m_dwPrevXRefOffset = xrefpos;
- if (m_dwPrevXRefOffset >= m_dwFileLen) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- } else {
- SetStartOffset(m_dwPrevXRefOffset);
- m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
- }
- }
- return true;
- }
+ uint32_t xrefpos = GetDirectInteger(pTrailerDict, "Prev");
+ if (!xrefpos) {
m_dwPrevXRefOffset = 0;
m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
return true;
}
- pHints->AddSegment(m_Pos, iTrailerSize);
- return false;
+
+ m_dwPrevXRefOffset = GetDirectInteger(pTrailerDict, "XRefStm");
+ if (m_dwPrevXRefOffset) {
+ m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
+ return true;
+ }
+
+ m_dwPrevXRefOffset = xrefpos;
+ if (m_dwPrevXRefOffset >= m_dwFileLen) {
+ m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
+ } else {
+ SetStartOffset(m_dwPrevXRefOffset);
+ m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
+ }
+ return true;
}
bool CPDF_DataAvail::CheckPage(uint32_t dwPage, DownloadHints* pHints) {
@@ -1172,42 +1177,47 @@ bool CPDF_DataAvail::CheckUnknownPageNode(uint32_t dwPageNo,
pPageNode->m_dwPageNo = dwPageNo;
CPDF_Dictionary* pDict = pPage->GetDict();
- CFX_ByteString type = pDict->GetStringFor("Type");
- if (type == "Pages") {
- pPageNode->m_type = PDF_PAGENODE_PAGES;
- CPDF_Object* pKids = pDict->GetObjectFor("Kids");
- if (!pKids) {
- m_docStatus = PDF_DATAAVAIL_PAGE;
- return true;
+ const CFX_ByteString type = pDict->GetStringFor("Type");
+ if (type == "Page") {
+ pPageNode->m_type = PDF_PAGENODE_PAGE;
+ return true;
+ }
+
+ if (type != "Pages") {
+ m_docStatus = PDF_DATAAVAIL_ERROR;
+ return false;
+ }
+
+ pPageNode->m_type = PDF_PAGENODE_PAGES;
+ CPDF_Object* pKids = pDict->GetObjectFor("Kids");
+ if (!pKids) {
+ m_docStatus = PDF_DATAAVAIL_PAGE;
+ return true;
+ }
+
+ switch (pKids->GetType()) {
+ case CPDF_Object::REFERENCE: {
+ CPDF_Reference* pKid = pKids->AsReference();
+ auto pNode = pdfium::MakeUnique<PageNode>();
+ pNode->m_dwPageNo = pKid->GetRefObjNum();
+ pPageNode->m_ChildNodes.push_back(std::move(pNode));
+ break;
}
+ case CPDF_Object::ARRAY: {
+ CPDF_Array* pKidsArray = pKids->AsArray();
+ for (size_t i = 0; i < pKidsArray->GetCount(); ++i) {
+ CPDF_Reference* pKid = ToReference(pKidsArray->GetObjectAt(i));
+ if (!pKid)
+ continue;
- switch (pKids->GetType()) {
- case CPDF_Object::REFERENCE: {
- CPDF_Reference* pKid = pKids->AsReference();
auto pNode = pdfium::MakeUnique<PageNode>();
pNode->m_dwPageNo = pKid->GetRefObjNum();
pPageNode->m_ChildNodes.push_back(std::move(pNode));
- } break;
- case CPDF_Object::ARRAY: {
- CPDF_Array* pKidsArray = pKids->AsArray();
- for (size_t i = 0; i < pKidsArray->GetCount(); ++i) {
- CPDF_Reference* pKid = ToReference(pKidsArray->GetObjectAt(i));
- if (!pKid)
- continue;
-
- auto pNode = pdfium::MakeUnique<PageNode>();
- pNode->m_dwPageNo = pKid->GetRefObjNum();
- pPageNode->m_ChildNodes.push_back(std::move(pNode));
- }
- } break;
- default:
- break;
+ }
+ break;
}
- } else if (type == "Page") {
- pPageNode->m_type = PDF_PAGENODE_PAGE;
- } else {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return false;
+ default:
+ break;
}
return true;
}
@@ -1469,21 +1479,20 @@ CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail(
return GetPage(dwPage) ? DataAvailable : DataError;
}
- if (m_bMainXRefLoadedOK) {
- if (m_bTotalLoadPageTree) {
- if (!LoadPages(pHints))
- return DataNotAvailable;
- } else {
- if (!m_bCurPageDictLoadOK && !CheckPage(dwPage, pHints))
- return DataNotAvailable;
- }
- } else {
+ if (!m_bMainXRefLoadedOK) {
if (!LoadAllFile(pHints))
return DataNotAvailable;
m_pDocument->GetParser()->RebuildCrossRef();
ResetFirstCheck(dwPage);
return DataAvailable;
}
+ if (m_bTotalLoadPageTree) {
+ if (!LoadPages(pHints))
+ return DataNotAvailable;
+ } else {
+ if (!m_bCurPageDictLoadOK && !CheckPage(dwPage, pHints))
+ return DataNotAvailable;
+ }
} else {
if (!m_bTotalLoadPageTree && !m_bCurPageDictLoadOK &&
!CheckPage(dwPage, pHints)) {