diff options
author | Artem Strygin <art-snake@yandex-team.ru> | 2017-10-02 19:19:28 +0300 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-10-02 16:29:30 +0000 |
commit | d8169d7607b5084cdeceee3eaffca0ab16d2c14d (patch) | |
tree | 7741388e44b50f8a330f4724fa5ce29d6a0097bf /core/fpdfapi/parser/cpdf_syntax_parser.cpp | |
parent | 73784e81928a664169f0ae013707fdfb0e82e70d (diff) | |
download | pdfium-d8169d7607b5084cdeceee3eaffca0ab16d2c14d.tar.xz |
Implement CPDF_CryptoHandler::DecryptObject
Decryption logic has been extracted from CPDF_SyntaxParser::GetObjectBody
into CPDF_CryptoHandler::DecryptObject
Performance comparison results:
https://pdfium-review.googlesource.com/c/pdfium/+/12970
Change-Id: Iaeaed56b7f96166bbbcf6db162192d2ba9af4698
Reviewed-on: https://pdfium-review.googlesource.com/12971
Commit-Queue: Art Snake <art-snake@yandex-team.ru>
Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'core/fpdfapi/parser/cpdf_syntax_parser.cpp')
-rw-r--r-- | core/fpdfapi/parser/cpdf_syntax_parser.cpp | 96 |
1 files changed, 17 insertions, 79 deletions
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp index ac401b351d..58cc60b85d 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp +++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp @@ -44,9 +44,7 @@ CPDF_SyntaxParser::CPDF_SyntaxParser() : CPDF_SyntaxParser(WeakPtr<ByteStringPool>()) {} CPDF_SyntaxParser::CPDF_SyntaxParser(const WeakPtr<ByteStringPool>& pPool) - : m_MetadataObjnum(0), - m_pFileAccess(nullptr), - m_pPool(pPool) {} + : m_pFileAccess(nullptr), m_pPool(pPool) {} CPDF_SyntaxParser::~CPDF_SyntaxParser() { } @@ -354,13 +352,9 @@ ByteString CPDF_SyntaxParser::GetKeyword() { } std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectBody( - CPDF_IndirectObjectHolder* pObjList, - uint32_t objnum, - uint32_t gennum, - bool bDecrypt) { + CPDF_IndirectObjectHolder* pObjList) { const CPDF_ReadValidator::Session read_session(GetValidator().Get()); - auto result = GetObjectBodyInternal(pObjList, objnum, gennum, bDecrypt, - ParseType::kLoose); + auto result = GetObjectBodyInternal(pObjList, ParseType::kLoose); if (GetValidator()->has_read_problems()) return nullptr; return result; @@ -368,9 +362,6 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectBody( std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectBodyInternal( CPDF_IndirectObjectHolder* pObjList, - uint32_t objnum, - uint32_t gennum, - bool bDecrypt, ParseType parse_type) { AutoRestorer<int> restorer(&s_CurrentRecursionDepth); if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) @@ -406,20 +397,16 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectBodyInternal( if (word == "(") { ByteString str = ReadString(); - if (m_pCryptoHandler && bDecrypt) - str = m_pCryptoHandler->Decrypt(objnum, gennum, str); return pdfium::MakeUnique<CPDF_String>(m_pPool, str, false); } if (word == "<") { ByteString str = ReadHexString(); - if (m_pCryptoHandler && bDecrypt) - str = m_pCryptoHandler->Decrypt(objnum, gennum, str); return pdfium::MakeUnique<CPDF_String>(m_pPool, str, true); } if (word == "[") { auto pArray = pdfium::MakeUnique<CPDF_Array>(); - while (std::unique_ptr<CPDF_Object> pObj = GetObjectBodyInternal( - pObjList, objnum, gennum, true, ParseType::kLoose)) { + while (std::unique_ptr<CPDF_Object> pObj = + GetObjectBodyInternal(pObjList, ParseType::kLoose)) { pArray->Add(std::move(pObj)); } return (parse_type == ParseType::kLoose || m_WordBuffer[0] == ']') @@ -432,7 +419,6 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectBodyInternal( PDF_NameDecode(ByteStringView(m_WordBuffer + 1, m_WordSize - 1))); } if (word == "<<") { - FX_FILESIZE dwSignValuePos = 0; std::unique_ptr<CPDF_Dictionary> pDict = pdfium::MakeUnique<CPDF_Dictionary>(m_pPool); while (1) { @@ -452,14 +438,12 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectBodyInternal( continue; key = PDF_NameDecode(key); - if (key == "/Contents") - dwSignValuePos = m_Pos; if (key.IsEmpty() && parse_type == ParseType::kLoose) continue; - std::unique_ptr<CPDF_Object> pObj = GetObjectBodyInternal( - pObjList, objnum, gennum, true, ParseType::kLoose); + std::unique_ptr<CPDF_Object> pObj = + GetObjectBodyInternal(pObjList, ParseType::kLoose); if (!pObj) { if (parse_type == ParseType::kLoose) continue; @@ -474,24 +458,13 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectBodyInternal( } } - // Only when this is a signature dictionary and has contents, we reset the - // contents to the un-decrypted form. - if (m_pCryptoHandler && bDecrypt && pDict->IsSignatureDict() && - dwSignValuePos) { - AutoRestorer<FX_FILESIZE> save_pos(&m_Pos); - m_Pos = dwSignValuePos; - pDict->SetFor("Contents", - GetObjectBodyInternal(pObjList, objnum, gennum, false, - ParseType::kLoose)); - } - FX_FILESIZE SavedPos = m_Pos; ByteString nextword = GetNextWord(nullptr); if (nextword != "stream") { m_Pos = SavedPos; return std::move(pDict); } - return ReadStream(std::move(pDict), objnum, gennum); + return ReadStream(std::move(pDict)); } if (word == ">>") m_Pos = SavedObjPos; @@ -500,13 +473,9 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectBodyInternal( } std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectBodyForStrict( - CPDF_IndirectObjectHolder* pObjList, - uint32_t objnum, - uint32_t gennum, - bool bDecrypt) { + CPDF_IndirectObjectHolder* pObjList) { const CPDF_ReadValidator::Session read_session(GetValidator().Get()); - auto result = GetObjectBodyInternal(pObjList, objnum, gennum, bDecrypt, - ParseType::kStrict); + auto result = GetObjectBodyInternal(pObjList, ParseType::kStrict); if (GetValidator()->has_read_problems()) return nullptr; return result; @@ -514,8 +483,6 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectBodyForStrict( std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetIndirectObject( CPDF_IndirectObjectHolder* pObjList, - uint32_t objnum, - bool bDecrypt, ParseType parse_type) { const CPDF_ReadValidator::Session read_session(GetValidator().Get()); const FX_FILESIZE saved_pos = GetPos(); @@ -525,30 +492,24 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetIndirectObject( SetPos(saved_pos); return nullptr; } - - uint32_t parser_objnum = FXSYS_atoui(word.c_str()); - if (objnum && parser_objnum != objnum) { - SetPos(saved_pos); - return nullptr; - } + const uint32_t parser_objnum = FXSYS_atoui(word.c_str()); word = GetNextWord(&is_number); if (!is_number || word.IsEmpty()) { SetPos(saved_pos); return nullptr; } - const uint32_t parser_gennum = FXSYS_atoui(word.c_str()); + if (GetKeyword() != "obj") { SetPos(saved_pos); return nullptr; } - std::unique_ptr<CPDF_Object> pObj = GetObjectBodyInternal( - pObjList, objnum, parser_gennum, bDecrypt, parse_type); + std::unique_ptr<CPDF_Object> pObj = + GetObjectBodyInternal(pObjList, parse_type); if (pObj) { - if (!objnum) - pObj->m_ObjNum = parser_objnum; + pObj->m_ObjNum = parser_objnum; pObj->m_GenNum = parser_gennum; } @@ -572,9 +533,7 @@ unsigned int CPDF_SyntaxParser::ReadEOLMarkers(FX_FILESIZE pos) { } std::unique_ptr<CPDF_Stream> CPDF_SyntaxParser::ReadStream( - std::unique_ptr<CPDF_Dictionary> pDict, - uint32_t objnum, - uint32_t gennum) { + std::unique_ptr<CPDF_Dictionary> pDict) { const CPDF_Number* pLenObj = ToNumber(pDict->GetDirectObjectFor("Length")); FX_FILESIZE len = pLenObj ? pLenObj->GetInteger() : -1; @@ -585,9 +544,6 @@ std::unique_ptr<CPDF_Stream> CPDF_SyntaxParser::ReadStream( const ByteStringView kEndStreamStr("endstream"); const ByteStringView kEndObjStr("endobj"); - CPDF_CryptoHandler* pCryptoHandler = - objnum == m_MetadataObjnum ? nullptr : m_pCryptoHandler.Get(); - if (!pCryptoHandler) { bool bSearchForKeyword = true; if (len >= 0) { pdfium::base::CheckedNumeric<FX_FILESIZE> pos = m_Pos; @@ -674,7 +630,7 @@ std::unique_ptr<CPDF_Stream> CPDF_SyntaxParser::ReadStream( pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(len)); } m_Pos = streamStartPos; - } + // Read up to the end of the buffer. Note, we allow zero length streams as // we need to pass them through when we are importing pages into a new // document. @@ -684,21 +640,8 @@ std::unique_ptr<CPDF_Stream> CPDF_SyntaxParser::ReadStream( std::unique_ptr<uint8_t, FxFreeDeleter> pData; if (len > 0) { - if (pCryptoHandler && pCryptoHandler->IsCipherAES() && len < 16) - return nullptr; - pData.reset(FX_Alloc(uint8_t, len)); ReadBlock(pData.get(), len); - if (pCryptoHandler) { - CFX_BinaryBuf dest_buf; - dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len)); - - void* context = pCryptoHandler->DecryptStart(objnum, gennum); - pCryptoHandler->DecryptStream(context, pData.get(), len, dest_buf); - pCryptoHandler->DecryptFinish(context, dest_buf); - len = dest_buf.GetSize(); - pData = dest_buf.DetachBuffer(); - } } auto pStream = pdfium::MakeUnique<CPDF_Stream>(std::move(pData), len, std::move(pDict)); @@ -834,11 +777,6 @@ FX_FILESIZE CPDF_SyntaxParser::FindTag(const ByteStringView& tag, return -1; } -void CPDF_SyntaxParser::SetEncrypt( - const RetainPtr<CPDF_CryptoHandler>& pCryptoHandler) { - m_pCryptoHandler = pCryptoHandler; -} - RetainPtr<IFX_SeekableReadStream> CPDF_SyntaxParser::GetFileAccess() const { return m_pFileAccess; } |