summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2018-12-13 09:40:49 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-03-29 09:55:48 +0000
commit4c53ce998eb7416575bbbdcf075e4872036eacc2 (patch)
tree9bb864690291bbe172bdd2e8bfa52eaae4fad3fc
parent195a52f52b31da5529d6bba21960e36952b0ab73 (diff)
downloadqtwebengine-chromium-4c53ce998eb7416575bbbdcf075e4872036eacc2.tar.gz
[Backport] CVE-2018-17481
Merge M71: Make public IndirectObjectHolder orphan tracking feature Original CL at https://pdfium-review.googlesource.com/c/45111 Manual merge to avoid conflicts. Bug: chromium:901654 Reviewed-on: https://pdfium-review.googlesource.com/c/45330 Change-Id: Ifdad31c5ef15b5d2479c571d43b00bd3edbca5e3 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
-rw-r--r--chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.cpp13
-rw-r--r--chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.h2
-rw-r--r--chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp10
-rw-r--r--chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder.h7
-rw-r--r--chromium/third_party/pdfium/core/fpdfdoc/cpdf_formfield.cpp31
-rw-r--r--chromium/third_party/pdfium/core/fpdfdoc/cpdf_interform.h2
6 files changed, 45 insertions, 20 deletions
diff --git a/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.cpp b/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.cpp
index 3621dbc1b73..30c330dd78e 100644
--- a/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -204,13 +204,14 @@ void CPDF_Dictionary::ConvertToIndirectObjectFor(
it->second = new CPDF_Reference(pHolder, pObj->GetObjNum());
}
-void CPDF_Dictionary::RemoveFor(const CFX_ByteString& key) {
+std::unique_ptr<CPDF_Object> CPDF_Dictionary::RemoveFor(const CFX_ByteString& key) {
+ std::unique_ptr<CPDF_Object> result;
auto it = m_Map.find(key);
- if (it == m_Map.end())
- return;
-
- delete it->second;
- m_Map.erase(it);
+ if (it != m_Map.end()) {
+ result = std::unique_ptr<CPDF_Object>(it->second);
+ m_Map.erase(it);
+ }
+ return result;
}
void CPDF_Dictionary::ReplaceKey(const CFX_ByteString& oldkey,
diff --git a/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.h b/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.h
index ebfd7e92eea..1c07a2bec55 100644
--- a/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.h
@@ -80,7 +80,7 @@ class CPDF_Dictionary : public CPDF_Object {
CPDF_IndirectObjectHolder* pHolder);
// Invalidates iterators for the element with the key |key|.
- void RemoveFor(const CFX_ByteString& key);
+ std::unique_ptr<CPDF_Object> RemoveFor(const CFX_ByteString& key);
// Invalidates iterators for the element with the key |oldkey|.
void ReplaceKey(const CFX_ByteString& oldkey, const CFX_ByteString& newkey);
diff --git a/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp b/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp
index d1183ebaf47..22dd1ada7df 100644
--- a/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp
+++ b/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp
@@ -52,7 +52,8 @@ CPDF_Object* CPDF_IndirectObjectHolder::AddIndirectObject(
CHECK(!pObj->m_ObjNum);
CPDF_Object* pUnowned = pObj.get();
pObj->m_ObjNum = ++m_LastObjNum;
- m_IndirectObjs[m_LastObjNum].release(); // TODO(tsepez): stop this leak.
+ AddOrphan(std::move(m_IndirectObjs[m_LastObjNum]));
+
m_IndirectObjs[m_LastObjNum] = std::move(pObj);
return pUnowned;
}
@@ -69,6 +70,7 @@ bool CPDF_IndirectObjectHolder::ReplaceIndirectObjectIfHigherGeneration(
return false;
pObj->m_ObjNum = objnum;
+ AddOrphan(std::move(m_IndirectObjs[objnum]));
m_IndirectObjs[objnum] = std::move(pObj);
m_LastObjNum = std::max(m_LastObjNum, objnum);
return true;
@@ -81,3 +83,9 @@ void CPDF_IndirectObjectHolder::DeleteIndirectObject(uint32_t objnum) {
m_IndirectObjs.erase(objnum);
}
+
+void CPDF_IndirectObjectHolder::AddOrphan(
+ std::unique_ptr<CPDF_Object> pObject) {
+ if (pObject)
+ m_OrphanObjs.push_back(std::move(pObject));
+}
diff --git a/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder.h b/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder.h
index a78e6663b37..87cf3d18d48 100644
--- a/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder.h
+++ b/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder.h
@@ -10,6 +10,7 @@
#include <map>
#include <memory>
#include <type_traits>
+#include <vector>
#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fxcrt/cfx_string_pool_template.h"
@@ -52,6 +53,11 @@ class CPDF_IndirectObjectHolder {
uint32_t objnum,
std::unique_ptr<CPDF_Object> pObj);
+ // Takes ownership of |pObj|, persist it for life of the indirect object
+ // holder (typically so that unowned pointers to it remain valid). No-op
+ // if |pObj| is NULL.
+ void AddOrphan(std::unique_ptr<CPDF_Object> pObj);
+
uint32_t GetLastObjNum() const { return m_LastObjNum; }
void SetLastObjNum(uint32_t objnum) { m_LastObjNum = objnum; }
@@ -68,6 +74,7 @@ class CPDF_IndirectObjectHolder {
private:
uint32_t m_LastObjNum;
std::map<uint32_t, std::unique_ptr<CPDF_Object>> m_IndirectObjs;
+ std::vector<std::unique_ptr<CPDF_Object>> m_OrphanObjs;
CFX_WeakPtr<CFX_ByteStringPool> m_pByteStringPool;
};
diff --git a/chromium/third_party/pdfium/core/fpdfdoc/cpdf_formfield.cpp b/chromium/third_party/pdfium/core/fpdfdoc/cpdf_formfield.cpp
index 3a2213f1aee..44c276924bd 100644
--- a/chromium/third_party/pdfium/core/fpdfdoc/cpdf_formfield.cpp
+++ b/chromium/third_party/pdfium/core/fpdfdoc/cpdf_formfield.cpp
@@ -223,14 +223,16 @@ bool CPDF_FormField::ResetField(bool bNotify) {
if (!pClone)
return false;
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("V"));
m_pDict->SetFor("V", pClone.release());
if (pRV) {
std::unique_ptr<CPDF_Object> pCloneR = pDV->Clone();
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("RV"));
m_pDict->SetFor("RV", pCloneR.release());
}
} else {
- m_pDict->RemoveFor("V");
- m_pDict->RemoveFor("RV");
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("V"));
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("RV"));
}
if (bNotify)
NotifyAfterValueChange();
@@ -361,15 +363,18 @@ bool CPDF_FormField::SetValue(const CFX_WideString& value,
if (bNotify && !NotifyBeforeValueChange(csValue))
return false;
+ CFX_ByteString key(bDefault ? "DV" : "V");
int iIndex = FindOptionValue(csValue);
if (iIndex < 0) {
CFX_ByteString bsEncodeText = PDF_EncodeText(csValue);
- m_pDict->SetStringFor(bDefault ? "DV" : "V", bsEncodeText);
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor(key));
+ m_pDict->SetStringFor(key, bsEncodeText);
if (m_Type == RichText && !bDefault)
m_pDict->SetStringFor("RV", bsEncodeText);
- m_pDict->RemoveFor("I");
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("I"));
} else {
- m_pDict->SetStringFor(bDefault ? "DV" : "V", PDF_EncodeText(csValue));
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor(key));
+ m_pDict->SetStringFor(key, PDF_EncodeText(csValue));
if (!bDefault) {
ClearSelection();
SetItemSelection(iIndex, true);
@@ -486,8 +491,8 @@ bool CPDF_FormField::ClearSelection(bool bNotify) {
if (!NotifyListOrComboBoxBeforeChange(csValue))
return false;
}
- m_pDict->RemoveFor("V");
- m_pDict->RemoveFor("I");
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("V"));
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("I"));
if (bNotify)
NotifyListOrComboBoxAfterChange();
return true;
@@ -573,7 +578,7 @@ bool CPDF_FormField::SetItemSelection(int index, bool bSelected, bool bNotify) {
SelectOption(index, false);
if (pValue->IsString()) {
if (pValue->GetUnicodeText() == opt_value)
- m_pDict->RemoveFor("V");
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("V"));
} else if (pValue->IsArray()) {
std::unique_ptr<CPDF_Array> pArray(new CPDF_Array);
for (int i = 0; i < CountOptions(); i++) {
@@ -582,12 +587,14 @@ bool CPDF_FormField::SetItemSelection(int index, bool bSelected, bool bNotify) {
pArray->AddNew<CPDF_String>(PDF_EncodeText(opt_value), false);
}
}
- if (pArray->GetCount() > 0)
+ if (pArray->GetCount() > 0) {
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("V"));
m_pDict->SetFor("V", pArray.release()); // std::move someday
+ }
}
} else {
- m_pDict->RemoveFor("V");
- m_pDict->RemoveFor("I");
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("V"));
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("I"));
}
}
}
@@ -888,7 +895,7 @@ bool CPDF_FormField::SelectOption(int iOptIndex, bool bSelected, bool bNotify) {
pArray->AddNew<CPDF_Number>(iOptIndex);
if (pArray->IsEmpty())
- m_pDict->RemoveFor("I");
+ m_pForm->GetDocument()->AddOrphan(m_pDict->RemoveFor("I"));
}
if (bNotify)
NotifyListOrComboBoxAfterChange();
diff --git a/chromium/third_party/pdfium/core/fpdfdoc/cpdf_interform.h b/chromium/third_party/pdfium/core/fpdfdoc/cpdf_interform.h
index fbff0289a1d..99fcb432f0e 100644
--- a/chromium/third_party/pdfium/core/fpdfdoc/cpdf_interform.h
+++ b/chromium/third_party/pdfium/core/fpdfdoc/cpdf_interform.h
@@ -89,6 +89,8 @@ class CPDF_InterForm {
bool HasXFAForm() const;
void FixPageFields(const CPDF_Page* pPage);
+ CPDF_Document* GetDocument() const { return m_pDocument; }
+
private:
friend class CPDF_FormControl;
friend class CPDF_FormField;