summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Strygin <art-snake@yandex-team.ru>2018-07-24 10:14:24 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-07-24 10:14:24 +0000
commitaa50728980036f07fda232cea974fd80c89b7cb7 (patch)
tree101e954b24a44f1d818923076695bd25759d6b14
parentc62aa207e9acb919c33df5f3694fe159619dda86 (diff)
downloadpdfium-aa50728980036f07fda232cea974fd80c89b7cb7.tar.xz
Fix encryption dictionary owning.
Return encryption dictionary as const reference from CPDF_Parser. Create a copy in CPDF_Creator if needed. Change-Id: I270f71d307d818fba7f65ebe379f5942ae816934 Reviewed-on: https://pdfium-review.googlesource.com/38390 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Art Snake <art-snake@yandex-team.ru>
-rw-r--r--core/fpdfapi/edit/cpdf_creator.cpp8
-rw-r--r--core/fpdfapi/edit/cpdf_creator.h3
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp66
-rw-r--r--core/fpdfapi/parser/cpdf_parser.h4
-rw-r--r--core/fpdfapi/parser/cpdf_security_handler.cpp8
-rw-r--r--fpdfsdk/fpdf_view.cpp2
6 files changed, 45 insertions, 46 deletions
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp
index 5d4fac478d..aa8c751046 100644
--- a/core/fpdfapi/edit/cpdf_creator.cpp
+++ b/core/fpdfapi/edit/cpdf_creator.cpp
@@ -619,10 +619,11 @@ void CPDF_Creator::InitID() {
if (m_pEncryptDict) {
ASSERT(m_pParser);
if (m_pEncryptDict->GetStringFor("Filter") == "Standard") {
- ByteString user_pass = m_pParser->GetPassword();
+ m_pNewEncryptDict = ToDictionary(m_pEncryptDict->Clone());
+ m_pEncryptDict = m_pNewEncryptDict.get();
m_pSecurityHandler = pdfium::MakeUnique<CPDF_SecurityHandler>();
- m_pSecurityHandler->OnCreate(m_pEncryptDict.Get(), m_pIDArray.get(),
- user_pass);
+ m_pSecurityHandler->OnCreate(m_pNewEncryptDict.get(), m_pIDArray.get(),
+ m_pParser->GetPassword());
m_bSecurityChanged = true;
}
}
@@ -666,6 +667,7 @@ void CPDF_Creator::RemoveSecurity() {
m_pSecurityHandler.Reset();
m_bSecurityChanged = true;
m_pEncryptDict = nullptr;
+ m_pNewEncryptDict.reset();
}
CPDF_CryptoHandler* CPDF_Creator::GetCryptoHandler() {
diff --git a/core/fpdfapi/edit/cpdf_creator.h b/core/fpdfapi/edit/cpdf_creator.h
index 39e0950af6..96643c882f 100644
--- a/core/fpdfapi/edit/cpdf_creator.h
+++ b/core/fpdfapi/edit/cpdf_creator.h
@@ -75,7 +75,8 @@ class CPDF_Creator {
UnownedPtr<CPDF_Document> const m_pDocument;
UnownedPtr<const CPDF_Parser> const m_pParser;
- UnownedPtr<CPDF_Dictionary> m_pEncryptDict;
+ UnownedPtr<const CPDF_Dictionary> m_pEncryptDict;
+ std::unique_ptr<CPDF_Dictionary> m_pNewEncryptDict;
fxcrt::MaybeOwned<CPDF_SecurityHandler> m_pSecurityHandler;
UnownedPtr<const CPDF_Object> m_pMetadata;
uint32_t m_dwLastObjNum;
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 4d3835795c..16077fd39e 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -119,10 +119,6 @@ bool CPDF_Parser::IsObjectFree(uint32_t objnum) const {
return GetObjectType(objnum) == ObjectType::kFree;
}
-void CPDF_Parser::SetEncryptDictionary(const CPDF_Dictionary* pDict) {
- m_pEncryptDict = pDict ? ToDictionary(pDict->Clone()) : nullptr;
-}
-
RetainPtr<IFX_SeekableReadStream> CPDF_Parser::GetFileAccess() const {
return m_pSyntax->GetFileAccess();
}
@@ -260,37 +256,24 @@ CPDF_Parser::Error CPDF_Parser::SetEncryptHandler() {
if (!GetTrailer())
return FORMAT_ERROR;
- const CPDF_Object* pEncryptObj = GetTrailer()->GetObjectFor("Encrypt");
- if (pEncryptObj) {
- if (const CPDF_Dictionary* pEncryptDict = pEncryptObj->AsDictionary()) {
- SetEncryptDictionary(pEncryptDict);
- } else if (const CPDF_Reference* pRef = pEncryptObj->AsReference()) {
- pEncryptObj =
- m_pObjectsHolder->GetOrParseIndirectObject(pRef->GetRefObjNum());
- if (pEncryptObj)
- SetEncryptDictionary(pEncryptObj->GetDict());
- }
- }
+ const CPDF_Dictionary* pEncryptDict = GetEncryptDict();
+ if (!pEncryptDict)
+ return SUCCESS;
- if (m_pEncryptDict) {
- ByteString filter = m_pEncryptDict->GetStringFor("Filter");
- if (filter != "Standard")
- return HANDLER_ERROR;
+ if (pEncryptDict->GetStringFor("Filter") != "Standard")
+ return HANDLER_ERROR;
- std::unique_ptr<CPDF_SecurityHandler> pSecurityHandler =
- pdfium::MakeUnique<CPDF_SecurityHandler>();
- if (!pSecurityHandler->OnInit(m_pEncryptDict.get(), GetIDArray(),
- m_Password))
- return PASSWORD_ERROR;
+ std::unique_ptr<CPDF_SecurityHandler> pSecurityHandler =
+ pdfium::MakeUnique<CPDF_SecurityHandler>();
+ if (!pSecurityHandler->OnInit(pEncryptDict, GetIDArray(), m_Password))
+ return PASSWORD_ERROR;
- m_pSecurityHandler = std::move(pSecurityHandler);
- }
+ m_pSecurityHandler = std::move(pSecurityHandler);
return SUCCESS;
}
void CPDF_Parser::ReleaseEncryptHandler() {
m_pSecurityHandler.reset();
- SetEncryptDictionary(nullptr);
}
// Ideally, all the cross reference entries should be verified.
@@ -828,6 +811,24 @@ CPDF_Dictionary* CPDF_Parser::GetRoot() const {
return obj ? obj->GetDict() : nullptr;
}
+const CPDF_Dictionary* CPDF_Parser::GetEncryptDict() const {
+ if (!GetTrailer())
+ return nullptr;
+
+ const CPDF_Object* pEncryptObj = GetTrailer()->GetObjectFor("Encrypt");
+ if (!pEncryptObj)
+ return nullptr;
+
+ if (pEncryptObj->IsDictionary())
+ return ToDictionary(pEncryptObj);
+
+ if (pEncryptObj->IsReference()) {
+ return ToDictionary(m_pObjectsHolder->GetOrParseIndirectObject(
+ pEncryptObj->AsReference()->GetRefObjNum()));
+ }
+ return nullptr;
+}
+
const CPDF_Dictionary* CPDF_Parser::GetTrailer() const {
return m_CrossRefTable->trailer();
}
@@ -954,16 +955,7 @@ std::unique_ptr<CPDF_Dictionary> CPDF_Parser::LoadTrailerV4() {
}
uint32_t CPDF_Parser::GetPermissions() const {
- if (!m_pSecurityHandler)
- return 0xFFFFFFFF;
-
- uint32_t dwPermission = m_pSecurityHandler->GetPermissions();
- if (m_pEncryptDict && m_pEncryptDict->GetStringFor("Filter") == "Standard") {
- // See PDF Reference 1.7, page 123, table 3.20.
- dwPermission &= 0xFFFFFFFC;
- dwPermission |= 0xFFFFF0C0;
- }
- return dwPermission;
+ return m_pSecurityHandler ? m_pSecurityHandler->GetPermissions() : 0xFFFFFFFF;
}
std::unique_ptr<CPDF_LinearizedHeader> CPDF_Parser::ParseLinearizedHeader() {
diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h
index 92aaf7df6a..0af39d7529 100644
--- a/core/fpdfapi/parser/cpdf_parser.h
+++ b/core/fpdfapi/parser/cpdf_parser.h
@@ -78,7 +78,7 @@ class CPDF_Parser {
const CPDF_Array* GetIDArray() const;
CPDF_Dictionary* GetRoot() const;
- CPDF_Dictionary* GetEncryptDict() const { return m_pEncryptDict.get(); }
+ const CPDF_Dictionary* GetEncryptDict() const;
std::unique_ptr<CPDF_Object> ParseIndirectObject(uint32_t objnum);
@@ -141,7 +141,6 @@ class CPDF_Parser {
Error LoadLinearizedMainXRefTable();
const CPDF_ObjectStream* GetObjectStream(uint32_t object_number);
std::unique_ptr<CPDF_LinearizedHeader> ParseLinearizedHeader();
- void SetEncryptDictionary(const CPDF_Dictionary* pDict);
void ShrinkObjectMap(uint32_t size);
// A simple check whether the cross reference table matches with
// the objects.
@@ -172,7 +171,6 @@ class CPDF_Parser {
// m_CrossRefTable must be destroyed after m_pSecurityHandler due to the
// ownership of the ID array data.
std::unique_ptr<CPDF_CrossRefTable> m_CrossRefTable;
- std::unique_ptr<CPDF_Dictionary> m_pEncryptDict;
FX_FILESIZE m_LastXRefOffset;
std::unique_ptr<CPDF_SecurityHandler> m_pSecurityHandler;
ByteString m_Password;
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index eeba53ef34..caa82a9ddd 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -119,7 +119,13 @@ bool CPDF_SecurityHandler::CheckSecurity(const ByteString& password) {
}
uint32_t CPDF_SecurityHandler::GetPermissions() const {
- return m_bOwnerUnlocked ? 0xFFFFFFFF : m_Permissions;
+ uint32_t dwPermission = m_bOwnerUnlocked ? 0xFFFFFFFF : m_Permissions;
+ if (m_pEncryptDict && m_pEncryptDict->GetStringFor("Filter") == "Standard") {
+ // See PDF Reference 1.7, page 123, table 3.20.
+ dwPermission &= 0xFFFFFFFC;
+ dwPermission |= 0xFFFFF0C0;
+ }
+ return dwPermission;
}
static bool LoadCryptInfo(const CPDF_Dictionary* pEncryptDict,
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 5fdc82af73..c44d582fd0 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -313,7 +313,7 @@ FPDF_GetSecurityHandlerRevision(FPDF_DOCUMENT document) {
if (!pDoc || !pDoc->GetParser())
return -1;
- CPDF_Dictionary* pDict = pDoc->GetParser()->GetEncryptDict();
+ const CPDF_Dictionary* pDict = pDoc->GetParser()->GetEncryptDict();
return pDict ? pDict->GetIntegerFor("R") : -1;
}