Add a GetOrCreateDict() helper function.
Making sure one dictionary contains another dictionary is a fairly
common task. Add a helper to make that less tedious.
Change-Id: I386fb05f1af8216924dafc710fc9d04bcf050328
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/91550
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 6f694bf..5bb0ff0 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -185,10 +185,9 @@
"Resources", m_pDocument.Get(),
m_pObjHolder->GetResources()->GetObjNum());
}
- CPDF_Dictionary* pResList = m_pObjHolder->GetResources()->GetDictFor(bsType);
- if (!pResList)
- pResList = m_pObjHolder->GetResources()->SetNewFor<CPDF_Dictionary>(bsType);
+ CPDF_Dictionary* pResList =
+ GetOrCreateDict(m_pObjHolder->GetResources(), bsType);
ByteString name;
int idnum = 1;
while (true) {
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp
index 6b01790..cccf189 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_utility.cpp
@@ -93,6 +93,13 @@
return pObj ? pObj->GetInteger() : 0;
}
+CPDF_Dictionary* GetOrCreateDict(CPDF_Dictionary* dict, const ByteString& key) {
+ CPDF_Dictionary* result = dict->GetDictFor(key);
+ if (result)
+ return result;
+ return dict->SetNewFor<CPDF_Dictionary>(key);
+}
+
ByteString PDF_NameDecode(ByteStringView orig) {
size_t src_size = orig.GetLength();
size_t out_index = 0;
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.h b/core/fpdfapi/parser/fpdf_parser_utility.h
index fbe87bd..2752610 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility.h
+++ b/core/fpdfapi/parser/fpdf_parser_utility.h
@@ -47,6 +47,8 @@
int32_t GetDirectInteger(const CPDF_Dictionary* pDict, const ByteString& key);
+CPDF_Dictionary* GetOrCreateDict(CPDF_Dictionary* dict, const ByteString& key);
+
ByteString PDF_NameDecode(ByteStringView orig);
ByteString PDF_NameEncode(const ByteString& orig);
diff --git a/core/fpdfdoc/cpdf_bafontmap.cpp b/core/fpdfdoc/cpdf_bafontmap.cpp
index db2f793..9813a75 100644
--- a/core/fpdfdoc/cpdf_bafontmap.cpp
+++ b/core/fpdfdoc/cpdf_bafontmap.cpp
@@ -278,9 +278,8 @@
if (!pFont)
return;
- CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictFor(pdfium::annotation::kAP);
- if (!pAPDict)
- pAPDict = m_pAnnotDict->SetNewFor<CPDF_Dictionary>(pdfium::annotation::kAP);
+ CPDF_Dictionary* pAPDict =
+ GetOrCreateDict(m_pAnnotDict.Get(), pdfium::annotation::kAP);
// to avoid checkbox and radiobutton
if (ToDictionary(pAPDict->GetObjectFor(m_sAPType)))
@@ -300,9 +299,7 @@
pStream->InitStream({}, std::move(pOwnedDict));
}
- CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
- if (!pStreamResList)
- pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
+ CPDF_Dictionary* pStreamResList = GetOrCreateDict(pStreamDict, "Resources");
CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font");
if (!pStreamResFontList) {
pStreamResFontList = m_pDocument->NewIndirect<CPDF_Dictionary>();
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp
index ff876f4..dc97759 100644
--- a/core/fpdfdoc/cpdf_generateap.cpp
+++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -511,10 +511,8 @@
CPDF_Stream* pNormalStream = pDoc->NewIndirect<CPDF_Stream>();
pNormalStream->SetDataFromStringstream(psAppStream);
- CPDF_Dictionary* pAPDict = pAnnotDict->GetDictFor(pdfium::annotation::kAP);
- if (!pAPDict)
- pAPDict = pAnnotDict->SetNewFor<CPDF_Dictionary>(pdfium::annotation::kAP);
-
+ CPDF_Dictionary* pAPDict =
+ GetOrCreateDict(pAnnotDict, pdfium::annotation::kAP);
pAPDict->SetNewFor<CPDF_Reference>("N", pDoc, pNormalStream->GetObjNum());
CPDF_Dictionary* pStreamDict = pNormalStream->GetDict();
@@ -1063,10 +1061,8 @@
rcBBox.right - fBorderWidth, rcBBox.top - fBorderWidth);
rcBody.Normalize();
- CPDF_Dictionary* pAPDict = pAnnotDict->GetDictFor(pdfium::annotation::kAP);
- if (!pAPDict)
- pAPDict = pAnnotDict->SetNewFor<CPDF_Dictionary>(pdfium::annotation::kAP);
-
+ CPDF_Dictionary* pAPDict =
+ GetOrCreateDict(pAnnotDict, pdfium::annotation::kAP);
CPDF_Stream* pNormalStream = pAPDict->GetStreamFor("N");
if (!pNormalStream) {
pNormalStream = pDoc->NewIndirect<CPDF_Stream>();
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index 9c2fcd1..355b056 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -247,13 +247,8 @@
return;
}
- CPDF_Dictionary* pDR = pFormDict->GetDictFor("DR");
- if (!pDR)
- pDR = pFormDict->SetNewFor<CPDF_Dictionary>("DR");
-
- CPDF_Dictionary* pFonts = pDR->GetDictFor("Font");
- if (!pFonts)
- pFonts = pDR->SetNewFor<CPDF_Dictionary>("Font");
+ CPDF_Dictionary* pDR = GetOrCreateDict(pFormDict, "DR");
+ CPDF_Dictionary* pFonts = GetOrCreateDict(pDR, "Font");
if (csNameTag->IsEmpty())
*csNameTag = pFont->GetBaseFontName();
diff --git a/fpdfsdk/cpdfsdk_appstream.cpp b/fpdfsdk/cpdfsdk_appstream.cpp
index 027cb1f..2edbc21 100644
--- a/fpdfsdk/cpdfsdk_appstream.cpp
+++ b/fpdfsdk/cpdfsdk_appstream.cpp
@@ -23,6 +23,7 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fpdfdoc/cpdf_bafontmap.h"
#include "core/fpdfdoc/cpdf_formcontrol.h"
#include "core/fpdfdoc/cpdf_icon.h"
@@ -1830,10 +1831,7 @@
if (pImageDict)
sImageAlias = pImageDict->GetStringFor("Name");
- CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
- if (!pStreamResList)
- pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
-
+ CPDF_Dictionary* pStreamResList = GetOrCreateDict(pStreamDict, "Resources");
CPDF_Dictionary* pXObject =
pStreamResList->SetNewFor<CPDF_Dictionary>("XObject");
pXObject->SetNewFor<CPDF_Reference>(sImageAlias,
@@ -1850,11 +1848,7 @@
pParentDict = dict_.Get();
key = sAPType;
} else {
- CPDF_Dictionary* pAPTypeDict = dict_->GetDictFor(sAPType);
- if (!pAPTypeDict)
- pAPTypeDict = dict_->SetNewFor<CPDF_Dictionary>(sAPType);
-
- pParentDict = pAPTypeDict;
+ pParentDict = GetOrCreateDict(dict_.Get(), sAPType);
key = sAPState;
}
diff --git a/fpdfsdk/cpdfsdk_baannot.cpp b/fpdfsdk/cpdfsdk_baannot.cpp
index 0860908..d9cbe5a 100644
--- a/fpdfsdk/cpdfsdk_baannot.cpp
+++ b/fpdfsdk/cpdfsdk_baannot.cpp
@@ -17,6 +17,7 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "third_party/base/check.h"
@@ -43,11 +44,7 @@
}
CPDF_Dictionary* CPDFSDK_BAAnnot::GetAPDict() const {
- CPDF_Dictionary* pAPDict =
- GetAnnotDict()->GetDictFor(pdfium::annotation::kAP);
- if (pAPDict)
- return pAPDict;
- return GetAnnotDict()->SetNewFor<CPDF_Dictionary>(pdfium::annotation::kAP);
+ return GetOrCreateDict(GetAnnotDict(), pdfium::annotation::kAP);
}
CFX_FloatRect CPDFSDK_BAAnnot::GetRect() const {
@@ -105,9 +102,7 @@
if (pBorder) {
pBorder->SetNewAt<CPDF_Number>(2, nWidth);
} else {
- CPDF_Dictionary* pBSDict = GetAnnotDict()->GetDictFor("BS");
- if (!pBSDict)
- pBSDict = GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS");
+ CPDF_Dictionary* pBSDict = GetOrCreateDict(GetAnnotDict(), "BS");
pBSDict->SetNewFor<CPDF_Number>("W", nWidth);
}
}
@@ -125,10 +120,7 @@
}
void CPDFSDK_BAAnnot::SetBorderStyle(BorderStyle nStyle) {
- CPDF_Dictionary* pBSDict = GetAnnotDict()->GetDictFor("BS");
- if (!pBSDict)
- pBSDict = GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS");
-
+ CPDF_Dictionary* pBSDict = GetOrCreateDict(GetAnnotDict(), "BS");
const char* name = nullptr;
switch (nStyle) {
case BorderStyle::kSolid:
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp
index 1efb188..0dcc58f 100644
--- a/fpdfsdk/fpdf_flatten.cpp
+++ b/fpdfsdk/fpdf_flatten.cpp
@@ -27,6 +27,7 @@
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fpdfdoc/cpdf_annot.h"
#include "core/fxcrt/fx_string_wrappers.h"
#include "fpdfsdk/cpdfsdk_helpers.h"
@@ -294,18 +295,10 @@
pPageDict->SetRectFor(pdfium::page_object::kCropBox, rcOriginalCB);
CPDF_Dictionary* pRes =
- pPageDict->GetDictFor(pdfium::page_object::kResources);
- if (!pRes) {
- pRes =
- pPageDict->SetNewFor<CPDF_Dictionary>(pdfium::page_object::kResources);
- }
-
+ GetOrCreateDict(pPageDict, pdfium::page_object::kResources);
CPDF_Stream* pNewXObject = pDocument->NewIndirect<CPDF_Stream>(
nullptr, 0, pDocument->New<CPDF_Dictionary>());
-
- CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject");
- if (!pPageXObject)
- pPageXObject = pRes->SetNewFor<CPDF_Dictionary>("XObject");
+ CPDF_Dictionary* pPageXObject = GetOrCreateDict(pRes, "XObject");
ByteString key;
if (!ObjectArray.empty()) {
@@ -397,10 +390,7 @@
pObjDict->SetNewFor<CPDF_Name>("Subtype", "Form");
}
- CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject");
- if (!pXObject)
- pXObject = pNewXORes->SetNewFor<CPDF_Dictionary>("XObject");
-
+ CPDF_Dictionary* pXObject = GetOrCreateDict(pNewXORes, "XObject");
ByteString sFormName = ByteString::Format("F%d", i);
pXObject->SetNewFor<CPDF_Reference>(sFormName, pDocument,
pObj->GetObjNum());
diff --git a/fpdfsdk/fpdf_ppo.cpp b/fpdfsdk/fpdf_ppo.cpp
index e80e44c..b307cac 100644
--- a/fpdfsdk/fpdf_ppo.cpp
+++ b/fpdfsdk/fpdf_ppo.cpp
@@ -29,6 +29,7 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fpdfapi/render/cpdf_pagerendercache.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/fx_string_wrappers.h"
@@ -669,16 +670,8 @@
DCHECK(pDestPageDict);
CPDF_Dictionary* pRes =
- pDestPageDict->GetDictFor(pdfium::page_object::kResources);
- if (!pRes) {
- pRes = pDestPageDict->SetNewFor<CPDF_Dictionary>(
- pdfium::page_object::kResources);
- }
-
- CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject");
- if (!pPageXObject)
- pPageXObject = pRes->SetNewFor<CPDF_Dictionary>("XObject");
-
+ GetOrCreateDict(pDestPageDict, pdfium::page_object::kResources);
+ CPDF_Dictionary* pPageXObject = GetOrCreateDict(pRes, "XObject");
for (auto& it : m_XObjectNameToNumberMap)
pPageXObject->SetNewFor<CPDF_Reference>(it.first, dest(), it.second);