Remove out parameter from CPDF_SyntaxParser::GetNextWord().
Change the return value to a struct to hold both the ByteString and the
bool.
Change-Id: Id7520989cdb378352456ff4e40f3bd56bfd049e4
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/85977
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp
index b9dc188..8e5c9d9 100644
--- a/core/fpdfapi/parser/cfdf_document.cpp
+++ b/core/fpdfapi/parser/cfdf_document.cpp
@@ -38,19 +38,18 @@
m_pFile = std::move(pFile);
CPDF_SyntaxParser parser(m_pFile);
while (1) {
- bool bNumber;
- ByteString word = parser.GetNextWord(&bNumber);
- if (bNumber) {
- uint32_t objnum = FXSYS_atoui(word.c_str());
+ CPDF_SyntaxParser::WordResult word_result = parser.GetNextWord();
+ if (word_result.is_number) {
+ uint32_t objnum = FXSYS_atoui(word_result.word.c_str());
if (!objnum)
break;
- word = parser.GetNextWord(&bNumber);
- if (!bNumber)
+ word_result = parser.GetNextWord();
+ if (!word_result.is_number)
break;
- word = parser.GetNextWord(nullptr);
- if (word != "obj")
+ word_result = parser.GetNextWord();
+ if (word_result.word != "obj")
break;
RetainPtr<CPDF_Object> pObj = parser.GetObjectBody(this);
@@ -58,11 +57,11 @@
break;
ReplaceIndirectObjectIfHigherGeneration(objnum, std::move(pObj));
- word = parser.GetNextWord(nullptr);
- if (word != "endobj")
+ word_result = parser.GetNextWord();
+ if (word_result.word != "endobj")
break;
} else {
- if (word != "trailer")
+ if (word_result.word != "trailer")
break;
RetainPtr<CPDF_Dictionary> pMainDict =
diff --git a/core/fpdfapi/parser/cpdf_linearized_header.cpp b/core/fpdfapi/parser/cpdf_linearized_header.cpp
index 256c2cc..2c927c7 100644
--- a/core/fpdfapi/parser/cpdf_linearized_header.cpp
+++ b/core/fpdfapi/parser/cpdf_linearized_header.cpp
@@ -72,7 +72,7 @@
}
// Move parser to the start of the xref table for the documents first page.
// (skpping endobj keyword)
- if (parser->GetNextWord(nullptr) != "endobj")
+ if (parser->GetNextWord().word != "endobj")
return nullptr;
auto result = pdfium::WrapUnique(
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 7ef9ed2..11e1cad 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -228,12 +228,12 @@
m_pSyntax->GetKeyword();
// Read XRef offset.
- bool bNumber;
- const ByteString xref_offset_str = m_pSyntax->GetNextWord(&bNumber);
- if (!bNumber || xref_offset_str.IsEmpty())
+ const CPDF_SyntaxParser::WordResult xref_offset_result =
+ m_pSyntax->GetNextWord();
+ if (!xref_offset_result.is_number || xref_offset_result.word.IsEmpty())
return 0;
- const FX_SAFE_FILESIZE result = FXSYS_atoi64(xref_offset_str.c_str());
+ const FX_SAFE_FILESIZE result = FXSYS_atoi64(xref_offset_result.word.c_str());
if (!result.IsValid() || result.ValueOrDie() >= m_pSyntax->GetDocumentSize())
return 0;
@@ -275,11 +275,10 @@
// Find the first non-zero position.
FX_FILESIZE SavedPos = m_pSyntax->GetPos();
m_pSyntax->SetPos(it.second.pos);
- bool is_num = false;
- ByteString num_str = m_pSyntax->GetNextWord(&is_num);
+ CPDF_SyntaxParser::WordResult word_result = m_pSyntax->GetNextWord();
m_pSyntax->SetPos(SavedPos);
- if (!is_num || num_str.IsEmpty() ||
- FXSYS_atoui(num_str.c_str()) != it.first) {
+ if (!word_result.is_number || word_result.word.IsEmpty() ||
+ FXSYS_atoui(word_result.word.c_str()) != it.first) {
// If the object number read doesn't match the one stored,
// something is wrong with the cross reference table.
return false;
@@ -511,12 +510,12 @@
std::vector<CrossRefObjData> result_objects;
while (1) {
FX_FILESIZE saved_pos = m_pSyntax->GetPos();
- bool bIsNumber;
- ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
+ CPDF_SyntaxParser::WordResult word_result = m_pSyntax->GetNextWord();
+ const ByteString& word = word_result.word;
if (word.IsEmpty())
return false;
- if (!bIsNumber) {
+ if (!word_result.is_number) {
m_pSyntax->SetPos(saved_pos);
break;
}
@@ -595,11 +594,11 @@
m_pSyntax->SetReadBufferSize(kBufferSize);
m_pSyntax->SetPos(0);
- bool bIsNumber;
std::vector<std::pair<uint32_t, FX_FILESIZE>> numbers;
- for (ByteString word = m_pSyntax->GetNextWord(&bIsNumber); !word.IsEmpty();
- word = m_pSyntax->GetNextWord(&bIsNumber)) {
- if (bIsNumber) {
+ for (CPDF_SyntaxParser::WordResult result = m_pSyntax->GetNextWord();
+ !result.word.IsEmpty(); result = m_pSyntax->GetNextWord()) {
+ const ByteString& word = result.word;
+ if (result.is_number) {
numbers.emplace_back(FXSYS_atoui(word.c_str()),
m_pSyntax->GetPos() - word.GetLength());
if (numbers.size() > 2u)
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index 3b65133..00c8746 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -464,24 +464,22 @@
m_Pos--;
}
-ByteString CPDF_SyntaxParser::GetNextWord(bool* bIsNumber) {
+CPDF_SyntaxParser::WordResult CPDF_SyntaxParser::GetNextWord() {
CPDF_ReadValidator::ScopedSession read_session(GetValidator());
WordType word_type = GetNextWordInternal();
- if (bIsNumber)
- *bIsNumber = word_type == WordType::kNumber;
- ByteString ret;
+ ByteString word;
if (!GetValidator()->has_read_problems())
- ret = ByteString(m_WordBuffer, m_WordSize);
- return ret;
+ word = ByteString(m_WordBuffer, m_WordSize);
+ return {word, word_type == WordType::kNumber};
}
ByteString CPDF_SyntaxParser::PeekNextWord() {
AutoRestorer<FX_FILESIZE> save_pos(&m_Pos);
- return GetNextWord(nullptr);
+ return GetNextWord().word;
}
ByteString CPDF_SyntaxParser::GetKeyword() {
- return GetNextWord(nullptr);
+ return GetNextWord().word;
}
void CPDF_SyntaxParser::SetPos(FX_FILESIZE pos) {
@@ -505,19 +503,19 @@
return nullptr;
FX_FILESIZE SavedObjPos = m_Pos;
- bool bIsNumber;
- ByteString word = GetNextWord(&bIsNumber);
+ WordResult word_result = GetNextWord();
+ const ByteString& word = word_result.word;
if (word.IsEmpty())
return nullptr;
- if (bIsNumber) {
+ if (word_result.is_number) {
AutoRestorer<FX_FILESIZE> pos_restorer(&m_Pos);
- ByteString nextword = GetNextWord(&bIsNumber);
- if (!bIsNumber)
+ WordResult nextword = GetNextWord();
+ if (!nextword.is_number)
return pdfium::MakeRetain<CPDF_Number>(word.AsStringView());
- ByteString nextword2 = GetNextWord(nullptr);
- if (nextword2 != "R")
+ WordResult nextword2 = GetNextWord();
+ if (nextword2.word != "R")
return pdfium::MakeRetain<CPDF_Number>(word.AsStringView());
pos_restorer.AbandonRestoration();
@@ -561,7 +559,8 @@
RetainPtr<CPDF_Dictionary> pDict =
pdfium::MakeRetain<CPDF_Dictionary>(m_pPool);
while (1) {
- ByteString inner_word = GetNextWord(nullptr);
+ WordResult inner_word_result = GetNextWord();
+ const ByteString& inner_word = inner_word_result.word;
if (inner_word.IsEmpty())
return nullptr;
@@ -599,7 +598,7 @@
}
AutoRestorer<FX_FILESIZE> pos_restorer(&m_Pos);
- if (GetNextWord(nullptr) != "stream")
+ if (GetNextWord().word != "stream")
return pDict;
pos_restorer.AbandonRestoration();
return ReadStream(std::move(pDict));
@@ -615,20 +614,21 @@
ParseType parse_type) {
CPDF_ReadValidator::ScopedSession read_session(GetValidator());
const FX_FILESIZE saved_pos = GetPos();
- bool is_number = false;
- ByteString word = GetNextWord(&is_number);
- if (!is_number || word.IsEmpty()) {
- SetPos(saved_pos);
- return nullptr;
- }
- const uint32_t parser_objnum = FXSYS_atoui(word.c_str());
- word = GetNextWord(&is_number);
- if (!is_number || word.IsEmpty()) {
+ WordResult objnum_word_result = GetNextWord();
+ if (!objnum_word_result.is_number || objnum_word_result.word.IsEmpty()) {
SetPos(saved_pos);
return nullptr;
}
- const uint32_t parser_gennum = FXSYS_atoui(word.c_str());
+ const uint32_t parser_objnum = FXSYS_atoui(objnum_word_result.word.c_str());
+
+ WordResult gennum_word_result = GetNextWord();
+ const ByteString& gennum_word = gennum_word_result.word;
+ if (!gennum_word_result.is_number || gennum_word.IsEmpty()) {
+ SetPos(saved_pos);
+ return nullptr;
+ }
+ const uint32_t parser_gennum = FXSYS_atoui(gennum_word.c_str());
if (GetKeyword() != "obj") {
SetPos(saved_pos);
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.h b/core/fpdfapi/parser/cpdf_syntax_parser.h
index 3d474fa..f8425f6 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.h
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.h
@@ -31,6 +31,11 @@
public:
enum class ParseType { kStrict, kLoose };
+ struct WordResult {
+ ByteString word;
+ bool is_number;
+ };
+
static std::unique_ptr<CPDF_SyntaxParser> CreateForTesting(
const RetainPtr<IFX_SeekableReadStream>& pFileAccess,
FX_FILESIZE HeaderOffset);
@@ -61,7 +66,7 @@
FX_FILESIZE FindTag(ByteStringView tag);
bool ReadBlock(uint8_t* pBuf, uint32_t size);
bool GetCharAt(FX_FILESIZE pos, uint8_t& ch);
- ByteString GetNextWord(bool* bIsNumber);
+ WordResult GetNextWord();
ByteString PeekNextWord();
const RetainPtr<CPDF_ReadValidator>& GetValidator() const {
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
index 47cec95..9c2bfa6 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
@@ -157,5 +157,5 @@
static const uint8_t data[] = " WORD ";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(data));
EXPECT_EQ("WORD", parser.PeekNextWord());
- EXPECT_EQ("WORD", parser.GetNextWord(nullptr));
+ EXPECT_EQ("WORD", parser.GetNextWord().word);
}
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index c061b76..86bfa7f 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -1262,34 +1262,33 @@
// Traverse the document.
syntax->SetPos(0);
while (1) {
- bool number;
- ByteString word = syntax->GetNextWord(&number);
- if (number) {
+ CPDF_SyntaxParser::WordResult word_result = syntax->GetNextWord();
+ if (word_result.is_number) {
// The object number was read. Read the generation number.
- word = syntax->GetNextWord(&number);
- if (!number)
+ word_result = syntax->GetNextWord();
+ if (!word_result.is_number)
break;
- word = syntax->GetNextWord(nullptr);
- if (word != "obj")
+ word_result = syntax->GetNextWord();
+ if (word_result.word != "obj")
break;
syntax->GetObjectBody(nullptr);
- word = syntax->GetNextWord(nullptr);
- if (word != "endobj")
+ word_result = syntax->GetNextWord();
+ if (word_result.word != "endobj")
break;
- } else if (word == "trailer") {
+ } else if (word_result.word == "trailer") {
syntax->GetObjectBody(nullptr);
- } else if (word == "startxref") {
- syntax->GetNextWord(nullptr);
- } else if (word == "xref") {
+ } else if (word_result.word == "startxref") {
+ syntax->GetNextWord();
+ } else if (word_result.word == "xref") {
while (1) {
- word = syntax->GetNextWord(nullptr);
- if (word.IsEmpty() || word == "startxref")
+ word_result = syntax->GetNextWord();
+ if (word_result.word.IsEmpty() || word_result.word == "startxref")
break;
}
- syntax->GetNextWord(nullptr);
+ syntax->GetNextWord();
} else {
break;
}