summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser/cpdf_parser.cpp
diff options
context:
space:
mode:
authorNicolas Pena <npm@chromium.org>2017-05-03 12:35:59 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-05-03 16:49:52 +0000
commit746babded81e9de3fc132fd670386382c031fa74 (patch)
treea1a7b6d68fc7aa8ff11c145955371371000b4fda /core/fpdfapi/parser/cpdf_parser.cpp
parent1e5a98afd195930de69f7b468a852717722377b6 (diff)
downloadpdfium-746babded81e9de3fc132fd670386382c031fa74.tar.xz
SetPos to at most the file length to avoid overflows
This CL prevents arbitrary position setting which may cause integer overflows. In the bug in question, the PDF says the xrefs are located in a huge position. This then causes problems when calling CPDF_SyntaxParser methods. Bug: chromium:603545 Change-Id: I5f94c38f46a0217e9f12f1bf8b2f3bee3b03cb35 Reviewed-on: https://pdfium-review.googlesource.com/4813 Commit-Queue: Nicolás Peña <npm@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org>
Diffstat (limited to 'core/fpdfapi/parser/cpdf_parser.cpp')
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp108
1 files changed, 54 insertions, 54 deletions
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 86428ab9d7..fc98be5f6e 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -155,12 +155,12 @@ CPDF_Parser::Error CPDF_Parser::StartParse(
if (m_pSyntax->m_FileLen < m_pSyntax->m_HeaderOffset + 9)
return FORMAT_ERROR;
- m_pSyntax->RestorePos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9);
+ m_pSyntax->SetPos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9);
m_pDocument = pDocument;
bool bXRefRebuilt = false;
if (m_pSyntax->SearchWord("startxref", true, false, 4096)) {
- m_SortedOffset.insert(m_pSyntax->SavePos());
+ m_SortedOffset.insert(m_pSyntax->GetPos());
m_pSyntax->GetKeyword();
bool bNumber;
@@ -286,11 +286,11 @@ bool CPDF_Parser::VerifyCrossRefV4() {
if (it.second.pos == 0)
continue;
// Find the first non-zero position.
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
- m_pSyntax->RestorePos(it.second.pos);
+ FX_FILESIZE SavedPos = m_pSyntax->GetPos();
+ m_pSyntax->SetPos(it.second.pos);
bool is_num = false;
CFX_ByteString num_str = m_pSyntax->GetNextWord(&is_num);
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
if (!is_num || num_str.IsEmpty() ||
FXSYS_atoui(num_str.c_str()) != it.first) {
// If the object number read doesn't match the one stored,
@@ -414,12 +414,12 @@ bool CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
uint32_t dwObjCount) {
FX_FILESIZE dwStartPos = pos - m_pSyntax->m_HeaderOffset;
- m_pSyntax->RestorePos(dwStartPos);
+ m_pSyntax->SetPos(dwStartPos);
m_SortedOffset.insert(pos);
uint32_t start_objnum = 0;
uint32_t count = dwObjCount;
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
+ FX_FILESIZE SavedPos = m_pSyntax->GetPos();
const int32_t recordsize = 20;
std::vector<char> buf(1024 * recordsize + 1);
@@ -465,14 +465,14 @@ bool CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
}
}
}
- m_pSyntax->RestorePos(SavedPos + count * recordsize);
+ m_pSyntax->SetPos(SavedPos + count * recordsize);
return true;
}
bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
FX_FILESIZE streampos,
bool bSkip) {
- m_pSyntax->RestorePos(pos);
+ m_pSyntax->SetPos(pos);
if (m_pSyntax->GetKeyword() != "xref")
return false;
@@ -481,14 +481,14 @@ bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
m_SortedOffset.insert(streampos);
while (1) {
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
+ FX_FILESIZE SavedPos = m_pSyntax->GetPos();
bool bIsNumber;
CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
if (word.IsEmpty())
return false;
if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
break;
}
@@ -498,7 +498,7 @@ bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
uint32_t count = m_pSyntax->GetDirectNum();
m_pSyntax->ToNextWord();
- SavedPos = m_pSyntax->SavePos();
+ SavedPos = m_pSyntax->GetPos();
const int32_t recordsize = 20;
m_dwXrefStartObjNum = start_objnum;
@@ -541,7 +541,7 @@ bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
}
}
}
- m_pSyntax->RestorePos(SavedPos + count * recordsize);
+ m_pSyntax->SetPos(SavedPos + count * recordsize);
}
return !streampos || LoadCrossRefV5(&streampos, false);
}
@@ -736,7 +736,7 @@ bool CPDF_Parser::RebuildCrossRef() {
}
FX_FILESIZE offset = 0;
- m_pSyntax->RestorePos(obj_pos);
+ m_pSyntax->SetPos(obj_pos);
offset = m_pSyntax->FindTag("obj", 0);
if (offset == -1)
offset = 0;
@@ -776,7 +776,7 @@ bool CPDF_Parser::RebuildCrossRef() {
if (inside_index == 7) {
if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) {
last_trailer = pos + i - 7;
- m_pSyntax->RestorePos(pos + i - m_pSyntax->m_HeaderOffset);
+ m_pSyntax->SetPos(pos + i - m_pSyntax->m_HeaderOffset);
std::unique_ptr<CPDF_Object> pObj =
m_pSyntax->GetObject(m_pDocument, 0, 0, true);
@@ -813,7 +813,7 @@ bool CPDF_Parser::RebuildCrossRef() {
m_pTrailer = ToDictionary(std::move(pObj));
}
- FX_FILESIZE dwSavePos = m_pSyntax->SavePos();
+ FX_FILESIZE dwSavePos = m_pSyntax->GetPos();
CFX_ByteString strWord = m_pSyntax->GetKeyword();
if (!strWord.Compare("startxref")) {
bool bNumber;
@@ -822,7 +822,7 @@ bool CPDF_Parser::RebuildCrossRef() {
if (bNumber)
m_LastXRefOffset = FXSYS_atoi(bsOffset.c_str());
}
- m_pSyntax->RestorePos(dwSavePos);
+ m_pSyntax->SetPos(dwSavePos);
}
}
}
@@ -1135,7 +1135,7 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject(
if (it == m_ObjCache[pObjStream].end())
return nullptr;
- syntax.RestorePos(offset + it->second);
+ syntax.SetPos(offset + it->second);
return syntax.GetObject(pObjList, 0, 0, true);
}
@@ -1229,43 +1229,43 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum,
if (pos == 0)
return;
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
- m_pSyntax->RestorePos(pos);
+ FX_FILESIZE SavedPos = m_pSyntax->GetPos();
+ m_pSyntax->SetPos(pos);
bool bIsNumber;
CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return;
}
uint32_t parser_objnum = FXSYS_atoui(word.c_str());
if (parser_objnum && parser_objnum != objnum) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return;
}
word = m_pSyntax->GetNextWord(&bIsNumber);
if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return;
}
if (m_pSyntax->GetKeyword() != "obj") {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return;
}
auto it = m_SortedOffset.find(pos);
if (it == m_SortedOffset.end() || ++it == m_SortedOffset.end()) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return;
}
FX_FILESIZE nextoff = *it;
bool bNextOffValid = false;
if (nextoff != pos) {
- m_pSyntax->RestorePos(nextoff);
+ m_pSyntax->SetPos(nextoff);
word = m_pSyntax->GetNextWord(&bIsNumber);
if (word == "xref") {
bNextOffValid = true;
@@ -1278,66 +1278,66 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum,
}
if (!bNextOffValid) {
- m_pSyntax->RestorePos(pos);
+ m_pSyntax->SetPos(pos);
while (1) {
if (m_pSyntax->GetKeyword() == "endobj")
break;
- if (m_pSyntax->SavePos() == m_pSyntax->m_FileLen)
+ if (m_pSyntax->GetPos() == m_pSyntax->m_FileLen)
break;
}
- nextoff = m_pSyntax->SavePos();
+ nextoff = m_pSyntax->GetPos();
}
size = (uint32_t)(nextoff - pos);
pBuffer = FX_Alloc(uint8_t, size);
- m_pSyntax->RestorePos(pos);
+ m_pSyntax->SetPos(pos);
m_pSyntax->ReadBlock(pBuffer, size);
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
}
std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAt(
CPDF_IndirectObjectHolder* pObjList,
FX_FILESIZE pos,
uint32_t objnum) {
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
- m_pSyntax->RestorePos(pos);
+ FX_FILESIZE SavedPos = m_pSyntax->GetPos();
+ m_pSyntax->SetPos(pos);
bool bIsNumber;
CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return nullptr;
}
- FX_FILESIZE objOffset = m_pSyntax->SavePos();
+ FX_FILESIZE objOffset = m_pSyntax->GetPos();
objOffset -= word.GetLength();
uint32_t parser_objnum = FXSYS_atoui(word.c_str());
if (objnum && parser_objnum != objnum) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return nullptr;
}
word = m_pSyntax->GetNextWord(&bIsNumber);
if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return nullptr;
}
uint32_t parser_gennum = FXSYS_atoui(word.c_str());
if (m_pSyntax->GetKeyword() != "obj") {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return nullptr;
}
std::unique_ptr<CPDF_Object> pObj =
m_pSyntax->GetObject(pObjList, objnum, parser_gennum, true);
- m_pSyntax->SavePos();
+ m_pSyntax->GetPos();
CFX_ByteString bsWord = m_pSyntax->GetKeyword();
if (bsWord == "endobj")
- m_pSyntax->SavePos();
+ m_pSyntax->GetPos();
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
if (pObj) {
if (!objnum)
pObj->m_ObjNum = parser_objnum;
@@ -1351,31 +1351,31 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAtByStrict(
FX_FILESIZE pos,
uint32_t objnum,
FX_FILESIZE* pResultPos) {
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
- m_pSyntax->RestorePos(pos);
+ FX_FILESIZE SavedPos = m_pSyntax->GetPos();
+ m_pSyntax->SetPos(pos);
bool bIsNumber;
CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return nullptr;
}
uint32_t parser_objnum = FXSYS_atoui(word.c_str());
if (objnum && parser_objnum != objnum) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return nullptr;
}
word = m_pSyntax->GetNextWord(&bIsNumber);
if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return nullptr;
}
uint32_t gennum = FXSYS_atoui(word.c_str());
if (m_pSyntax->GetKeyword() != "obj") {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return nullptr;
}
@@ -1385,7 +1385,7 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAtByStrict(
if (pResultPos)
*pResultPos = m_pSyntax->m_Pos;
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return pObj;
}
@@ -1417,9 +1417,9 @@ bool CPDF_Parser::IsLinearizedFile(
const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess,
uint32_t offset) {
m_pSyntax->InitParser(pFileAccess, offset);
- m_pSyntax->RestorePos(m_pSyntax->m_HeaderOffset + 9);
+ m_pSyntax->SetPos(m_pSyntax->m_HeaderOffset + 9);
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
+ FX_FILESIZE SavedPos = m_pSyntax->GetPos();
bool bIsNumber;
CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
if (!bIsNumber)
@@ -1432,7 +1432,7 @@ bool CPDF_Parser::IsLinearizedFile(
uint32_t gennum = FXSYS_atoui(word.c_str());
if (m_pSyntax->GetKeyword() != "obj") {
- m_pSyntax->RestorePos(SavedPos);
+ m_pSyntax->SetPos(SavedPos);
return false;
}
@@ -1465,7 +1465,7 @@ CPDF_Parser::Error CPDF_Parser::StartLinearizedParse(
m_bHasParsed = true;
m_pDocument = pDocument;
- FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos();
+ FX_FILESIZE dwFirstXRefOffset = m_pSyntax->GetPos();
bool bXRefRebuilt = false;
bool bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, false);
if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, true)) {
@@ -1549,7 +1549,7 @@ CPDF_Parser::Error CPDF_Parser::LoadLinearizedMainXRefTable() {
uint32_t dwSaveMetadataObjnum = m_pSyntax->m_MetadataObjnum;
m_pSyntax->m_MetadataObjnum = 0;
m_pTrailer.reset();
- m_pSyntax->RestorePos(m_LastXRefOffset - m_pSyntax->m_HeaderOffset);
+ m_pSyntax->SetPos(m_LastXRefOffset - m_pSyntax->m_HeaderOffset);
uint8_t ch = 0;
uint32_t dwCount = 0;
@@ -1557,7 +1557,7 @@ CPDF_Parser::Error CPDF_Parser::LoadLinearizedMainXRefTable() {
while (PDFCharIsWhitespace(ch)) {
++dwCount;
if (m_pSyntax->m_FileLen <=
- (FX_FILESIZE)(m_pSyntax->SavePos() + m_pSyntax->m_HeaderOffset)) {
+ (FX_FILESIZE)(m_pSyntax->GetPos() + m_pSyntax->m_HeaderOffset)) {
break;
}
m_pSyntax->GetNextChar(ch);