From d1a8458e6390103e123e9d265040b3d02c16955b Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 2 Aug 2017 17:41:22 -0700 Subject: Avoid a redundant header offset check in CPDF_Parser. CPDF_Parser::StartLinearizedParse() calls StartParse(), but already knows the PDF header offset. Refactor StartParse() so it does not have to look for the header again. Change-Id: Id8cc39301ae72da868dafc53921622d5b28ce26e Reviewed-on: https://pdfium-review.googlesource.com/9830 Commit-Queue: Lei Zhang Reviewed-by: Art Snake --- core/fpdfapi/parser/cpdf_data_avail.cpp | 2 +- core/fpdfapi/parser/cpdf_parser.cpp | 26 +++++++++++++++++++------- core/fpdfapi/parser/cpdf_parser.h | 3 +++ core/fpdfapi/parser/fpdf_parser_utility.cpp | 4 ++-- core/fpdfapi/parser/fpdf_parser_utility.h | 6 ++++++ 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp index 88755a9eb7..46c71a5ab9 100644 --- a/core/fpdfapi/parser/cpdf_data_avail.cpp +++ b/core/fpdfapi/parser/cpdf_data_avail.cpp @@ -754,7 +754,7 @@ bool CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, uint32_t dwLen) { auto file = pdfium::MakeRetain( pData, static_cast(dwLen), false); int32_t offset = GetHeaderOffset(file); - if (offset == -1) { + if (offset == kInvalidHeaderOffset) { m_docStatus = PDF_DATAAVAIL_ERROR; return false; } diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index e33cec0165..d669f24674 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp @@ -148,14 +148,26 @@ void CPDF_Parser::ShrinkObjectMap(uint32_t objnum) { CPDF_Parser::Error CPDF_Parser::StartParse( const CFX_RetainPtr& pFileAccess, CPDF_Document* pDocument) { + return StartParseInternal(pFileAccess, pDocument, kInvalidHeaderOffset); +} + +CPDF_Parser::Error CPDF_Parser::StartParseInternal( + const CFX_RetainPtr& pFileAccess, + CPDF_Document* pDocument, + int32_t iHeaderOffset) { ASSERT(!m_bHasParsed); m_bHasParsed = true; m_bXRefStream = false; m_LastXRefOffset = 0; - int32_t offset = GetHeaderOffset(pFileAccess); - if (offset == -1) - return FORMAT_ERROR; + int32_t offset; + if (iHeaderOffset == kInvalidHeaderOffset) { + offset = GetHeaderOffset(pFileAccess); + if (offset == kInvalidHeaderOffset) + return FORMAT_ERROR; + } else { + offset = iHeaderOffset; + } m_pSyntax->InitParser(pFileAccess, offset); @@ -1521,12 +1533,12 @@ CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( m_LastXRefOffset = 0; int32_t offset = GetHeaderOffset(pFileAccess); - if (offset == -1) + if (offset == kInvalidHeaderOffset) return FORMAT_ERROR; - if (!IsLinearizedFile(pFileAccess, offset)) { - return StartParse(pFileAccess, std::move(pDocument)); - } + if (!IsLinearizedFile(pFileAccess, offset)) + return StartParseInternal(pFileAccess, std::move(pDocument), offset); + m_bHasParsed = true; m_pDocument = pDocument; diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h index 759d042360..189de168f4 100644 --- a/core/fpdfapi/parser/cpdf_parser.h +++ b/core/fpdfapi/parser/cpdf_parser.h @@ -153,6 +153,9 @@ class CPDF_Parser { ObjectInfo info; }; + Error StartParseInternal(const CFX_RetainPtr& pFile, + CPDF_Document* pDocument, + int32_t iHeaderOffset); CPDF_Object* ParseDirect(CPDF_Object* pObj); bool LoadAllCrossRefV4(FX_FILESIZE pos); bool LoadAllCrossRefV5(FX_FILESIZE pos); diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp index 8323426e74..0c0ca6644f 100644 --- a/core/fpdfapi/parser/fpdf_parser_utility.cpp +++ b/core/fpdfapi/parser/fpdf_parser_utility.cpp @@ -75,12 +75,12 @@ int32_t GetHeaderOffset(const CFX_RetainPtr& pFile) { uint8_t buf[kBufSize]; for (int32_t offset = 0; offset <= 1024; ++offset) { if (!pFile->ReadBlock(buf, offset, kBufSize)) - return -1; + return kInvalidHeaderOffset; if (memcmp(buf, "%PDF", 4) == 0) return offset; } - return -1; + return kInvalidHeaderOffset; } int32_t GetDirectInteger(CPDF_Dictionary* pDict, const CFX_ByteString& key) { diff --git a/core/fpdfapi/parser/fpdf_parser_utility.h b/core/fpdfapi/parser/fpdf_parser_utility.h index eb8442ac68..5e764ad07b 100644 --- a/core/fpdfapi/parser/fpdf_parser_utility.h +++ b/core/fpdfapi/parser/fpdf_parser_utility.h @@ -34,7 +34,13 @@ inline bool PDFCharIsLineEnding(uint8_t c) { return c == '\r' || c == '\n'; } +constexpr int32_t kInvalidHeaderOffset = -1; + +// On success, return a positive offset value to the PDF header.. If the header +// cannot be found, or if there is an error reading from |pFile|, then return +// |kInvalidHeaderOffset|. int32_t GetHeaderOffset(const CFX_RetainPtr& pFile); + int32_t GetDirectInteger(CPDF_Dictionary* pDict, const CFX_ByteString& key); CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj); -- cgit v1.2.3