summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/parser/cfdf_document.cpp5
-rw-r--r--core/fpdfapi/parser/cpdf_crypto_handler.cpp113
-rw-r--r--core/fpdfapi/parser/cpdf_crypto_handler.h24
-rw-r--r--core/fpdfapi/parser/cpdf_data_avail.cpp6
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.cpp6
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp41
-rw-r--r--core/fpdfapi/parser/cpdf_parser.h3
-rw-r--r--core/fpdfapi/parser/cpdf_syntax_parser.cpp96
-rw-r--r--core/fpdfapi/parser/cpdf_syntax_parser.h22
-rw-r--r--core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp3
10 files changed, 182 insertions, 137 deletions
diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp
index 9c833cedcf..55493b257d 100644
--- a/core/fpdfapi/parser/cfdf_document.cpp
+++ b/core/fpdfapi/parser/cfdf_document.cpp
@@ -66,8 +66,7 @@ void CFDF_Document::ParseStream(
if (word != "obj")
break;
- std::unique_ptr<CPDF_Object> pObj =
- parser.GetObjectBody(this, objnum, 0, false);
+ std::unique_ptr<CPDF_Object> pObj = parser.GetObjectBody(this);
if (!pObj)
break;
@@ -80,7 +79,7 @@ void CFDF_Document::ParseStream(
break;
std::unique_ptr<CPDF_Dictionary> pMainDict =
- ToDictionary(parser.GetObjectBody(this, 0, 0, false));
+ ToDictionary(parser.GetObjectBody(this));
if (pMainDict)
m_pRootDict = pMainDict->GetDictFor("Root");
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.cpp b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
index cae95f2c19..441ca8000d 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
@@ -8,10 +8,41 @@
#include <time.h>
+#include <stack>
+#include <utility>
+
#include "core/fdrm/crypto/fx_crypt.h"
+#include "core/fpdfapi/edit/cpdf_encryptor.h"
+#include "core/fpdfapi/edit/cpdf_flateencoder.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_object_walker.h"
#include "core/fpdfapi/parser/cpdf_parser.h"
#include "core/fpdfapi/parser/cpdf_security_handler.h"
#include "core/fpdfapi/parser/cpdf_simple_parser.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+
+namespace {
+
+constexpr char kContentsKey[] = "Contents";
+constexpr char kTypeKey[] = "Type";
+constexpr char kFTKey[] = "FT";
+constexpr char kSignTypeValue[] = "Sig";
+
+} // namespace
+
+// static
+bool CPDF_CryptoHandler::IsSignatureDictionary(
+ const CPDF_Dictionary* dictionary) {
+ if (!dictionary)
+ return false;
+ const CPDF_Object* type_obj = dictionary->GetDirectObjectFor(kTypeKey);
+ if (!type_obj)
+ type_obj = dictionary->GetDirectObjectFor(kFTKey);
+ return type_obj && type_obj->GetString() == kSignTypeValue;
+}
void CPDF_CryptoHandler::CryptBlock(bool bEncrypt,
uint32_t objnum,
@@ -301,6 +332,88 @@ bool CPDF_CryptoHandler::IsCipherAES() const {
return m_Cipher == FXCIPHER_AES;
}
+std::unique_ptr<CPDF_Object> CPDF_CryptoHandler::DecryptObjectTree(
+ std::unique_ptr<CPDF_Object> object) {
+ if (!object)
+ return nullptr;
+
+ struct MayBeSignature {
+ const CPDF_Dictionary* parent;
+ CPDF_Object* contents;
+ };
+
+ std::stack<MayBeSignature> may_be_sign_dictionaries;
+ const uint32_t obj_num = object->GetObjNum();
+ const uint32_t gen_num = object->GetGenNum();
+
+ CPDF_Object* object_to_decrypt = object.get();
+ while (object_to_decrypt) {
+ CPDF_NonConstObjectWalker walker(object_to_decrypt);
+ object_to_decrypt = nullptr;
+ while (CPDF_Object* child = walker.GetNext()) {
+ const CPDF_Dictionary* parent_dict =
+ walker.GetParent() ? walker.GetParent()->GetDict() : nullptr;
+ if (walker.dictionary_key() == kContentsKey &&
+ (parent_dict->KeyExist(kTypeKey) || parent_dict->KeyExist(kFTKey))) {
+ // This object may be contents of signature dictionary.
+ // But now values of 'Type' and 'FT' of dictionary keys are encrypted,
+ // and we can not check this.
+ // Temporary skip it, to prevent signature corruption.
+ // It will be decrypted on next interations, if this is not contents of
+ // signature dictionary.
+ may_be_sign_dictionaries.push(MayBeSignature({parent_dict, child}));
+ walker.SkipWalkIntoCurrentObject();
+ continue;
+ }
+ // Strings decryption.
+ if (child->IsString()) {
+ // TODO(art-snake): Move decryption into the CPDF_String class.
+ CPDF_String* str = child->AsString();
+ str->SetString(Decrypt(obj_num, gen_num, str->GetString()));
+ }
+ // Stream decryption.
+ if (child->IsStream()) {
+ // TODO(art-snake): Move decryption into the CPDF_Stream class.
+ CPDF_Stream* stream = child->AsStream();
+ auto stream_access = pdfium::MakeRetain<CPDF_StreamAcc>(stream);
+ stream_access->LoadAllData(true);
+
+ if (IsCipherAES() && stream_access->GetSize() < 16) {
+ stream->SetData(nullptr, 0);
+ continue;
+ }
+
+ CFX_BinaryBuf decrypted_buf;
+ decrypted_buf.EstimateSize(DecryptGetSize(stream_access->GetSize()));
+
+ void* context = DecryptStart(obj_num, gen_num);
+ bool decrypt_result =
+ DecryptStream(context, stream_access->GetData(),
+ stream_access->GetSize(), decrypted_buf);
+ decrypt_result &= DecryptFinish(context, decrypted_buf);
+ if (decrypt_result) {
+ const uint32_t decrypted_size = decrypted_buf.GetSize();
+ stream->SetData(decrypted_buf.DetachBuffer(), decrypted_size);
+ } else {
+ // Decryption failed, set the stream to empty
+ stream->SetData(nullptr, 0);
+ }
+ }
+ }
+ // Signature dictionaries check.
+ while (!may_be_sign_dictionaries.empty()) {
+ auto dict_and_contents = std::move(may_be_sign_dictionaries.top());
+ may_be_sign_dictionaries.pop();
+ if (!IsSignatureDictionary(dict_and_contents.parent)) {
+ // This is not signature dictionary. Do decrypt its contents.
+ object_to_decrypt = dict_and_contents.contents;
+ break;
+ }
+ }
+ }
+ return object;
+}
+
bool CPDF_CryptoHandler::DecryptStream(void* context,
const uint8_t* src_buf,
uint32_t src_size,
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.h b/core/fpdfapi/parser/cpdf_crypto_handler.h
index d815e786f6..60f32b70ba 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.h
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.h
@@ -17,6 +17,7 @@
#include "core/fxcrt/retain_ptr.h"
class CPDF_Dictionary;
+class CPDF_Object;
class CPDF_SecurityHandler;
class CPDF_CryptoHandler : public Retainable {
@@ -24,16 +25,14 @@ class CPDF_CryptoHandler : public Retainable {
template <typename T, typename... Args>
friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+ static bool IsSignatureDictionary(const CPDF_Dictionary* dictionary);
+
bool Init(CPDF_Dictionary* pEncryptDict,
CPDF_SecurityHandler* pSecurityHandler);
- uint32_t DecryptGetSize(uint32_t src_size);
- void* DecryptStart(uint32_t objnum, uint32_t gennum);
- ByteString Decrypt(uint32_t objnum, uint32_t gennum, const ByteString& str);
- bool DecryptStream(void* context,
- const uint8_t* src_buf,
- uint32_t src_size,
- CFX_BinaryBuf& dest_buf);
- bool DecryptFinish(void* context, CFX_BinaryBuf& dest_buf);
+
+ std::unique_ptr<CPDF_Object> DecryptObjectTree(
+ std::unique_ptr<CPDF_Object> object);
+
uint32_t EncryptGetSize(uint32_t objnum,
uint32_t version,
const uint8_t* src_buf,
@@ -52,6 +51,15 @@ class CPDF_CryptoHandler : public Retainable {
CPDF_CryptoHandler();
~CPDF_CryptoHandler() override;
+ uint32_t DecryptGetSize(uint32_t src_size);
+ void* DecryptStart(uint32_t objnum, uint32_t gennum);
+ ByteString Decrypt(uint32_t objnum, uint32_t gennum, const ByteString& str);
+ bool DecryptStream(void* context,
+ const uint8_t* src_buf,
+ uint32_t src_size,
+ CFX_BinaryBuf& dest_buf);
+ bool DecryptFinish(void* context, CFX_BinaryBuf& dest_buf);
+
void PopulateKey(uint32_t objnum, uint32_t gennum, uint8_t* key);
void CryptBlock(bool bEncrypt,
uint32_t objnum,
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index 1db0470f37..8b378aab0e 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -670,14 +670,12 @@ std::unique_ptr<CPDF_Object> CPDF_DataAvail::ParseIndirectObjectAt(
if (!bIsNumber)
return nullptr;
- uint32_t gennum = FXSYS_atoui(word.c_str());
if (m_syntaxParser.GetKeyword() != "obj") {
m_syntaxParser.SetPos(SavedPos);
return nullptr;
}
- std::unique_ptr<CPDF_Object> pObj =
- m_syntaxParser.GetObjectBody(pObjList, parser_objnum, gennum, false);
+ std::unique_ptr<CPDF_Object> pObj = m_syntaxParser.GetObjectBody(pObjList);
m_syntaxParser.SetPos(SavedPos);
return pObj;
}
@@ -923,7 +921,7 @@ bool CPDF_DataAvail::CheckTrailer() {
const CPDF_ReadValidator::Session read_session(GetValidator().Get());
m_syntaxParser.SetPos(m_dwTrailerOffset);
const std::unique_ptr<CPDF_Object> pTrailer =
- m_syntaxParser.GetObjectBody(nullptr, 0, 0, false);
+ m_syntaxParser.GetObjectBody(nullptr);
if (!pTrailer) {
if (!GetValidator()->has_read_problems())
m_docStatus = PDF_DATAAVAIL_ERROR;
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index 5cdcf34f81..1e7f6a9a9b 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -11,6 +11,7 @@
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_boolean.h"
+#include "core/fpdfapi/parser/cpdf_crypto_handler.h"
#include "core/fpdfapi/parser/cpdf_name.h"
#include "core/fpdfapi/parser/cpdf_number.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
@@ -167,10 +168,7 @@ bool CPDF_Dictionary::KeyExist(const ByteString& key) const {
}
bool CPDF_Dictionary::IsSignatureDict() const {
- CPDF_Object* pType = GetDirectObjectFor("Type");
- if (!pType)
- pType = GetDirectObjectFor("FT");
- return pType && pType->GetString() == "Sig";
+ return CPDF_CryptoHandler::IsSignatureDictionary(this);
}
CPDF_Object* CPDF_Dictionary::SetFor(const ByteString& key,
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 6643cf5123..40d1b49ed6 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -22,6 +22,7 @@
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/cpdf_syntax_parser.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
+#include "core/fxcrt/autorestorer.h"
#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_safe_types.h"
@@ -165,7 +166,7 @@ void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) {
}
RetainPtr<CPDF_CryptoHandler> CPDF_Parser::GetCryptoHandler() const {
- return m_pSyntax->m_pCryptoHandler;
+ return m_pCryptoHandler;
}
RetainPtr<IFX_SeekableReadStream> CPDF_Parser::GetFileAccess() const {
@@ -292,7 +293,7 @@ CPDF_Parser::Error CPDF_Parser::StartParseInternal(CPDF_Document* pDocument) {
CPDF_Reference* pMetadata =
ToReference(m_pDocument->GetRoot()->GetObjectFor("Metadata"));
if (pMetadata)
- m_pSyntax->m_MetadataObjnum = pMetadata->GetRefObjNum();
+ m_MetadataObjnum = pMetadata->GetRefObjNum();
}
return SUCCESS;
}
@@ -327,13 +328,13 @@ CPDF_Parser::Error CPDF_Parser::SetEncryptHandler() {
auto pCryptoHandler = pdfium::MakeRetain<CPDF_CryptoHandler>();
if (!pCryptoHandler->Init(m_pEncryptDict.Get(), m_pSecurityHandler.get()))
return HANDLER_ERROR;
- m_pSyntax->SetEncrypt(pCryptoHandler);
+ m_pCryptoHandler = pCryptoHandler;
}
return SUCCESS;
}
void CPDF_Parser::ReleaseEncryptHandler() {
- m_pSyntax->m_pCryptoHandler.Reset();
+ m_pCryptoHandler.Reset();
m_pSecurityHandler.reset();
SetEncryptDictionary(nullptr);
}
@@ -876,7 +877,7 @@ bool CPDF_Parser::RebuildCrossRef() {
m_pSyntax->SetPos(pos + i - m_pSyntax->m_HeaderOffset);
std::unique_ptr<CPDF_Object> pObj =
- m_pSyntax->GetObjectBody(m_pDocument.Get(), 0, 0, false);
+ m_pSyntax->GetObjectBody(m_pDocument.Get());
if (pObj) {
if (pObj->IsDictionary() || pObj->AsStream()) {
CPDF_Stream* pStream = pObj->AsStream();
@@ -1237,7 +1238,7 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject(
return nullptr;
syntax.SetPos(offset + it->second);
- return syntax.GetObjectBody(pObjList, 0, 0, false);
+ return syntax.GetObjectBody(pObjList);
}
RetainPtr<CPDF_StreamAcc> CPDF_Parser::GetObjectStream(uint32_t objnum) {
@@ -1275,11 +1276,19 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAtInternal(
FX_FILESIZE* pResultPos) {
const FX_FILESIZE saved_pos = m_pSyntax->GetPos();
m_pSyntax->SetPos(pos);
- auto result =
- m_pSyntax->GetIndirectObject(pObjList, objnum, true, parse_type);
+ auto result = m_pSyntax->GetIndirectObject(pObjList, parse_type);
+
if (pResultPos)
*pResultPos = m_pSyntax->GetPos();
m_pSyntax->SetPos(saved_pos);
+
+ if (result && objnum && result->GetObjNum() != objnum)
+ return nullptr;
+
+ const bool should_decrypt = m_pCryptoHandler && objnum != m_MetadataObjnum;
+ if (should_decrypt)
+ result = m_pCryptoHandler->DecryptObjectTree(std::move(result));
+
return result;
}
@@ -1300,7 +1309,7 @@ std::unique_ptr<CPDF_Dictionary> CPDF_Parser::LoadTrailerV4() {
if (m_pSyntax->GetKeyword() != "trailer")
return nullptr;
- return ToDictionary(m_pSyntax->GetObjectBody(m_pDocument.Get(), 0, 0, false));
+ return ToDictionary(m_pSyntax->GetObjectBody(m_pDocument.Get()));
}
uint32_t CPDF_Parser::GetPermissions() const {
@@ -1325,19 +1334,17 @@ bool CPDF_Parser::ParseLinearizedHeader() {
if (!bIsNumber)
return false;
- uint32_t objnum = FXSYS_atoui(word.c_str());
word = m_pSyntax->GetNextWord(&bIsNumber);
if (!bIsNumber)
return false;
- uint32_t gennum = FXSYS_atoui(word.c_str());
if (m_pSyntax->GetKeyword() != "obj") {
m_pSyntax->SetPos(SavedPos);
return false;
}
- m_pLinearized = CPDF_LinearizedHeader::CreateForObject(
- m_pSyntax->GetObjectBody(nullptr, objnum, gennum, false));
+ m_pLinearized =
+ CPDF_LinearizedHeader::CreateForObject(m_pSyntax->GetObjectBody(nullptr));
if (!m_pLinearized)
return false;
@@ -1421,7 +1428,7 @@ CPDF_Parser::Error CPDF_Parser::StartLinearizedParse(
if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) {
if (CPDF_Reference* pMetadata =
ToReference(m_pDocument->GetRoot()->GetObjectFor("Metadata")))
- m_pSyntax->m_MetadataObjnum = pMetadata->GetRefObjNum();
+ m_MetadataObjnum = pMetadata->GetRefObjNum();
}
return SUCCESS;
}
@@ -1446,8 +1453,8 @@ bool CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) {
}
CPDF_Parser::Error CPDF_Parser::LoadLinearizedMainXRefTable() {
- uint32_t dwSaveMetadataObjnum = m_pSyntax->m_MetadataObjnum;
- m_pSyntax->m_MetadataObjnum = 0;
+ const AutoRestorer<uint32_t> save_metadata_objnum(&m_MetadataObjnum);
+ m_MetadataObjnum = 0;
m_pSyntax->SetPos(m_LastXRefOffset - m_pSyntax->m_HeaderOffset);
uint8_t ch = 0;
@@ -1474,10 +1481,8 @@ CPDF_Parser::Error CPDF_Parser::LoadLinearizedMainXRefTable() {
m_dwLinearizedFirstPageXRefStartObjNum) &&
!LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) {
m_LastXRefOffset = 0;
- m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum;
return FORMAT_ERROR;
}
- m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum;
return SUCCESS;
}
diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h
index fe3fe1084f..75d58e2e40 100644
--- a/core/fpdfapi/parser/cpdf_parser.h
+++ b/core/fpdfapi/parser/cpdf_parser.h
@@ -216,6 +216,9 @@ class CPDF_Parser {
// All indirect object numbers that are being parsed.
std::set<uint32_t> m_ParsingObjNums;
+
+ RetainPtr<CPDF_CryptoHandler> m_pCryptoHandler;
+ uint32_t m_MetadataObjnum = 0;
};
#endif // CORE_FPDFAPI_PARSER_CPDF_PARSER_H_
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;
}
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.h b/core/fpdfapi/parser/cpdf_syntax_parser.h
index 2326362692..d025905858 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.h
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.h
@@ -40,21 +40,13 @@ class CPDF_SyntaxParser {
void SetPos(FX_FILESIZE pos) { m_Pos = std::min(pos, m_FileLen); }
std::unique_ptr<CPDF_Object> GetObjectBody(
- CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum,
- uint32_t gennum,
- bool bDecrypt);
+ CPDF_IndirectObjectHolder* pObjList);
std::unique_ptr<CPDF_Object> GetObjectBodyForStrict(
- CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum,
- uint32_t gennum,
- bool bDecrypt);
+ CPDF_IndirectObjectHolder* pObjList);
std::unique_ptr<CPDF_Object> GetIndirectObject(
CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum,
- bool bDecrypt,
ParseType parse_type);
ByteString GetKeyword();
@@ -62,7 +54,6 @@ class CPDF_SyntaxParser {
void ToNextWord();
bool BackwardsSearchToWord(const ByteStringView& word, FX_FILESIZE limit);
FX_FILESIZE FindTag(const ByteStringView& tag, FX_FILESIZE limit);
- void SetEncrypt(const RetainPtr<CPDF_CryptoHandler>& pCryptoHandler);
bool ReadBlock(uint8_t* pBuf, uint32_t size);
bool GetCharAt(FX_FILESIZE pos, uint8_t& ch);
ByteString GetNextWord(bool* bIsNumber);
@@ -96,27 +87,20 @@ class CPDF_SyntaxParser {
ByteString ReadHexString();
unsigned int ReadEOLMarkers(FX_FILESIZE pos);
std::unique_ptr<CPDF_Stream> ReadStream(
- std::unique_ptr<CPDF_Dictionary> pDict,
- uint32_t objnum,
- uint32_t gennum);
+ std::unique_ptr<CPDF_Dictionary> pDict);
bool IsPositionRead(FX_FILESIZE pos) const;
std::unique_ptr<CPDF_Object> GetObjectBodyInternal(
CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum,
- uint32_t gennum,
- bool bDecrypt,
ParseType parse_type);
FX_FILESIZE m_Pos;
- uint32_t m_MetadataObjnum;
RetainPtr<CPDF_ReadValidator> m_pFileAccess;
FX_FILESIZE m_HeaderOffset;
FX_FILESIZE m_FileLen;
std::vector<uint8_t> m_pFileBuf;
FX_FILESIZE m_BufOffset;
- RetainPtr<CPDF_CryptoHandler> m_pCryptoHandler;
uint8_t m_WordBuffer[257];
uint32_t m_WordSize;
WeakPtr<ByteStringPool> m_pPool;
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
index af559c5ba6..cb065eb4e2 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
@@ -151,8 +151,7 @@ TEST(cpdf_syntax_parser, GetInvalidReference) {
// Data with a reference with number CPDF_Object::kInvalidObjNum
uint8_t data[] = "4294967295 0 R";
parser.InitParser(pdfium::MakeRetain<CFX_MemoryStream>(data, 14, false), 0);
- std::unique_ptr<CPDF_Object> ref =
- parser.GetObjectBody(nullptr, CPDF_Object::kInvalidObjNum, 0, false);
+ std::unique_ptr<CPDF_Object> ref = parser.GetObjectBody(nullptr);
EXPECT_FALSE(ref);
}