Make some parser utility functions into CPDF_Dictionary methods. And return retained references where reasonable. Change-Id: I5d7b1f35528d3040de8d4296ca2b4637e7c25755 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/94758 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp index c4588c7..983768b 100644 --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -186,8 +186,8 @@ m_pObjHolder->GetResources()->GetObjNum()); } - CPDF_Dictionary* pResList = - GetOrCreateDict(m_pObjHolder->GetMutableResources().Get(), bsType); + RetainPtr<CPDF_Dictionary> pResList = + m_pObjHolder->GetMutableResources()->GetOrCreateDictFor(bsType); ByteString name; int idnum = 1; while (true) {
diff --git a/core/fpdfapi/parser/cpdf_cross_ref_avail.cpp b/core/fpdfapi/parser/cpdf_cross_ref_avail.cpp index 90b0f6c..52c0af2 100644 --- a/core/fpdfapi/parser/cpdf_cross_ref_avail.cpp +++ b/core/fpdfapi/parser/cpdf_cross_ref_avail.cpp
@@ -150,14 +150,13 @@ return false; } - const int32_t xrefpos = - GetDirectInteger(trailer.Get(), kPrevCrossRefFieldKey); + const int32_t xrefpos = trailer->GetDirectIntegerFor(kPrevCrossRefFieldKey); if (xrefpos > 0 && pdfium::base::IsValueInRangeForNumericType<FX_FILESIZE>(xrefpos)) AddCrossRefForCheck(static_cast<FX_FILESIZE>(xrefpos)); const int32_t stream_xref_offset = - GetDirectInteger(trailer.Get(), kPrevCrossRefStreamOffsetFieldKey); + trailer->GetDirectIntegerFor(kPrevCrossRefStreamOffsetFieldKey); if (stream_xref_offset > 0 && pdfium::base::IsValueInRangeForNumericType<FX_FILESIZE>( stream_xref_offset))
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp index 10c05d8..d707524 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.cpp +++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -139,6 +139,11 @@ return p ? p->GetInteger() : def; } +int CPDF_Dictionary::GetDirectIntegerFor(const ByteString& key) const { + const CPDF_Number* p = ToNumber(GetObjectFor(key)); + return p ? p->GetInteger() : 0; +} + float CPDF_Dictionary::GetNumberFor(const ByteString& key) const { const CPDF_Object* p = GetObjectFor(key); return p ? p->GetNumber() : 0; @@ -161,6 +166,14 @@ return pdfium::WrapRetain(const_cast<CPDF_Dictionary*>(GetDictFor(key))); } +RetainPtr<CPDF_Dictionary> CPDF_Dictionary::GetOrCreateDictFor( + const ByteString& key) { + RetainPtr<CPDF_Dictionary> result = GetMutableDictFor(key); + if (result) + return result; + return pdfium::WrapRetain(SetNewFor<CPDF_Dictionary>(key)); +} + const CPDF_Array* CPDF_Dictionary::GetArrayFor(const ByteString& key) const { return ToArray(GetDirectObjectFor(key)); } @@ -170,6 +183,14 @@ return pdfium::WrapRetain(const_cast<CPDF_Array*>(GetArrayFor(key))); } +RetainPtr<CPDF_Array> CPDF_Dictionary::GetOrCreateArrayFor( + const ByteString& key) { + RetainPtr<CPDF_Array> result = GetMutableArrayFor(key); + if (result) + return result; + return pdfium::WrapRetain(SetNewFor<CPDF_Array>(key)); +} + const CPDF_Stream* CPDF_Dictionary::GetStreamFor(const ByteString& key) const { return ToStream(GetDirectObjectFor(key)); }
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h index 8fbb742..21c6135 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.h +++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -66,11 +66,14 @@ bool GetBooleanFor(const ByteString& key, bool bDefault) const; int GetIntegerFor(const ByteString& key) const; int GetIntegerFor(const ByteString& key, int default_int) const; + int GetDirectIntegerFor(const ByteString& key) const; float GetNumberFor(const ByteString& key) const; const CPDF_Dictionary* GetDictFor(const ByteString& key) const; RetainPtr<CPDF_Dictionary> GetMutableDictFor(const ByteString& key); + RetainPtr<CPDF_Dictionary> GetOrCreateDictFor(const ByteString& key); const CPDF_Array* GetArrayFor(const ByteString& key) const; RetainPtr<CPDF_Array> GetMutableArrayFor(const ByteString& key); + RetainPtr<CPDF_Array> GetOrCreateArrayFor(const ByteString& key); const CPDF_Stream* GetStreamFor(const ByteString& key) const; RetainPtr<CPDF_Stream> GetMutableStreamFor(const ByteString& key); CFX_FloatRect GetRectFor(const ByteString& key) const;
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp index fd4522e..c67a790 100644 --- a/core/fpdfapi/parser/cpdf_document.cpp +++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -463,7 +463,7 @@ return false; if (iPage == nPages) { - CPDF_Array* pPagesList = GetOrCreateArray(pPages.Get(), "Kids"); + RetainPtr<CPDF_Array> pPagesList = pPages->GetOrCreateArrayFor("Kids"); pPagesList->AppendNew<CPDF_Reference>(this, pPageDict->GetObjNum()); pPages->SetNewFor<CPDF_Number>("Count", nPages + 1); pPageDict->SetNewFor<CPDF_Reference>("Parent", this, pPages->GetObjNum());
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index 4a96e5a..2eecb88 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -356,18 +356,18 @@ return false; m_CrossRefTable->SetTrailer(std::move(trailer)); - int32_t xrefsize = GetDirectInteger(GetTrailer(), "Size"); + const int32_t xrefsize = GetTrailer()->GetDirectIntegerFor("Size"); if (xrefsize > 0 && xrefsize <= kMaxXRefSize) ShrinkObjectMap(xrefsize); - FX_FILESIZE xref_stm = GetDirectInteger(GetTrailer(), "XRefStm"); + FX_FILESIZE xref_stm = GetTrailer()->GetDirectIntegerFor("XRefStm"); std::vector<FX_FILESIZE> xref_stream_list{xref_stm}; std::vector<FX_FILESIZE> xref_list{xref_offset}; std::set<FX_FILESIZE> seen_xref_offset{xref_offset}; // When the trailer doesn't have Prev entry or Prev entry value is not // numerical, GetDirectInteger() returns 0. Loading will end. - xref_offset = GetDirectInteger(GetTrailer(), "Prev"); + xref_offset = GetTrailer()->GetDirectIntegerFor("Prev"); while (xref_offset > 0) { // Check for circular references. if (pdfium::Contains(seen_xref_offset, xref_offset)) @@ -383,7 +383,7 @@ if (!pDict) return false; - xref_offset = GetDirectInteger(pDict.Get(), "Prev"); + xref_offset = pDict->GetDirectIntegerFor("Prev"); xref_stm = pDict->GetIntegerFor("XRefStm"); xref_stream_list.insert(xref_stream_list.begin(), xref_stm); @@ -415,13 +415,13 @@ return false; // GetTrailer() currently returns the first-page trailer. - if (GetDirectInteger(GetTrailer(), "Size") == 0) + if (GetTrailer()->GetDirectIntegerFor("Size") == 0) return false; // Read /XRefStm from the first-page trailer. No need to read /Prev for the // first-page trailer, as the caller already did that and passed it in as // |main_xref_offset|. - FX_FILESIZE xref_stm = GetDirectInteger(GetTrailer(), "XRefStm"); + FX_FILESIZE xref_stm = GetTrailer()->GetDirectIntegerFor("XRefStm"); std::vector<FX_FILESIZE> xref_stream_list{xref_stm}; std::vector<FX_FILESIZE> xref_list{main_xref_offset}; std::set<FX_FILESIZE> seen_xref_offset{main_xref_offset}; @@ -433,7 +433,7 @@ // Now GetTrailer() returns the merged trailer, where /Prev is from the // main-trailer. - FX_FILESIZE xref_offset = GetDirectInteger(GetTrailer(), "Prev"); + FX_FILESIZE xref_offset = GetTrailer()->GetDirectIntegerFor("Prev"); while (xref_offset > 0) { // Check for circular references. if (pdfium::Contains(seen_xref_offset, xref_offset)) @@ -449,7 +449,7 @@ if (!pDict) return false; - xref_offset = GetDirectInteger(pDict.Get(), "Prev"); + xref_offset = pDict->GetDirectIntegerFor("Prev"); xref_stm = pDict->GetIntegerFor("XRefStm"); xref_stream_list.insert(xref_stream_list.begin(), xref_stm); @@ -1049,7 +1049,7 @@ return SUCCESS; m_CrossRefTable->SetTrailer(std::move(trailer)); - int32_t xrefsize = GetDirectInteger(GetTrailer(), "Size"); + const int32_t xrefsize = GetTrailer()->GetDirectIntegerFor("Size"); if (xrefsize > 0) ShrinkObjectMap(xrefsize); }
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp index b19e15d..90ea075 100644 --- a/core/fpdfapi/parser/fpdf_parser_utility.cpp +++ b/core/fpdfapi/parser/fpdf_parser_utility.cpp
@@ -88,25 +88,6 @@ return absl::nullopt; } -int32_t GetDirectInteger(const CPDF_Dictionary* pDict, const ByteString& key) { - const CPDF_Number* pObj = ToNumber(pDict->GetObjectFor(key)); - return pObj ? pObj->GetInteger() : 0; -} - -CPDF_Array* GetOrCreateArray(CPDF_Dictionary* dict, const ByteString& key) { - RetainPtr<CPDF_Array> result = dict->GetMutableArrayFor(key); - if (result) - return result.Get(); - return dict->SetNewFor<CPDF_Array>(key); -} - -CPDF_Dictionary* GetOrCreateDict(CPDF_Dictionary* dict, const ByteString& key) { - RetainPtr<CPDF_Dictionary> result = dict->GetMutableDictFor(key); - if (result) - return result.Get(); - 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 1bf3c74..5b6e209 100644 --- a/core/fpdfapi/parser/fpdf_parser_utility.h +++ b/core/fpdfapi/parser/fpdf_parser_utility.h
@@ -45,11 +45,6 @@ absl::optional<FX_FILESIZE> GetHeaderOffset( const RetainPtr<IFX_SeekableReadStream>& pFile); -int32_t GetDirectInteger(const CPDF_Dictionary* pDict, const ByteString& key); - -CPDF_Array* GetOrCreateArray(CPDF_Dictionary* dict, 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 2123ecd..ccc98e2 100644 --- a/core/fpdfdoc/cpdf_bafontmap.cpp +++ b/core/fpdfdoc/cpdf_bafontmap.cpp
@@ -291,8 +291,8 @@ if (!pFont) return; - CPDF_Dictionary* pAPDict = - GetOrCreateDict(m_pAnnotDict.Get(), pdfium::annotation::kAP); + RetainPtr<CPDF_Dictionary> pAPDict = + m_pAnnotDict->GetOrCreateDictFor(pdfium::annotation::kAP); // to avoid checkbox and radiobutton if (ToDictionary(pAPDict->GetObjectFor(m_sAPType))) @@ -312,8 +312,8 @@ pStream->InitStream({}, std::move(pOwnedDict)); } - CPDF_Dictionary* pStreamResList = - GetOrCreateDict(pStreamDict.Get(), "Resources"); + RetainPtr<CPDF_Dictionary> pStreamResList = + pStreamDict->GetOrCreateDictFor("Resources"); RetainPtr<CPDF_Dictionary> pStreamResFontList = pStreamResList->GetMutableDictFor("Font"); if (!pStreamResFontList) {
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp index 3b4d38e..29e1ec6 100644 --- a/core/fpdfdoc/cpdf_formfield.cpp +++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -747,7 +747,7 @@ } void CPDF_FormField::SelectOption(int iOptIndex) { - CPDF_Array* pArray = GetOrCreateArray(m_pDict.Get(), "I"); + RetainPtr<CPDF_Array> pArray = m_pDict->GetOrCreateArrayFor("I"); for (size_t i = 0; i < pArray->size(); i++) { int iFind = pArray->GetIntegerAt(i); if (iFind == iOptIndex)
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp index 9a1d8f8..0f1b674 100644 --- a/core/fpdfdoc/cpdf_generateap.cpp +++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -513,8 +513,8 @@ CPDF_Stream* pNormalStream = pDoc->NewIndirect<CPDF_Stream>(); pNormalStream->SetDataFromStringstream(psAppStream); - CPDF_Dictionary* pAPDict = - GetOrCreateDict(pAnnotDict, pdfium::annotation::kAP); + RetainPtr<CPDF_Dictionary> pAPDict = + pAnnotDict->GetOrCreateDictFor(pdfium::annotation::kAP); pAPDict->SetNewFor<CPDF_Reference>("N", pDoc, pNormalStream->GetObjNum()); RetainPtr<CPDF_Dictionary> pStreamDict = pNormalStream->GetMutableDict(); @@ -1066,8 +1066,8 @@ rcBBox.right - fBorderWidth, rcBBox.top - fBorderWidth); rcBody.Normalize(); - CPDF_Dictionary* pAPDict = - GetOrCreateDict(pAnnotDict, pdfium::annotation::kAP); + RetainPtr<CPDF_Dictionary> pAPDict = + pAnnotDict->GetOrCreateDictFor(pdfium::annotation::kAP); RetainPtr<CPDF_Stream> pNormalStream = pAPDict->GetMutableStreamFor("N"); if (!pNormalStream) { pNormalStream = pDoc->NewIndirect<CPDF_Stream>();
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp index 76b9f61..6e18e8d 100644 --- a/core/fpdfdoc/cpdf_interactiveform.cpp +++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -250,14 +250,14 @@ return; } - CPDF_Dictionary* pDR = GetOrCreateDict(pFormDict, "DR"); - CPDF_Dictionary* pFonts = GetOrCreateDict(pDR, "Font"); + RetainPtr<CPDF_Dictionary> pDR = pFormDict->GetOrCreateDictFor("DR"); + RetainPtr<CPDF_Dictionary> pFonts = pDR->GetOrCreateDictFor("Font"); if (csNameTag->IsEmpty()) *csNameTag = pFont->GetBaseFontName(); csNameTag->Remove(' '); - *csNameTag = GenerateNewFontResourceName(pDR, *csNameTag); + *csNameTag = GenerateNewFontResourceName(pDR.Get(), *csNameTag); pFonts->SetNewFor<CPDF_Reference>(*csNameTag, pDocument, pFont->GetFontDict()->GetObjNum()); }
diff --git a/fpdfsdk/cpdfsdk_appstream.cpp b/fpdfsdk/cpdfsdk_appstream.cpp index c5885bd..7d0033c 100644 --- a/fpdfsdk/cpdfsdk_appstream.cpp +++ b/fpdfsdk/cpdfsdk_appstream.cpp
@@ -1833,8 +1833,8 @@ if (pImageDict) sImageAlias = pImageDict->GetStringFor("Name"); - CPDF_Dictionary* pStreamResList = - GetOrCreateDict(pStreamDict.Get(), "Resources"); + RetainPtr<CPDF_Dictionary> pStreamResList = + pStreamDict->GetOrCreateDictFor("Resources"); CPDF_Dictionary* pXObject = pStreamResList->SetNewFor<CPDF_Dictionary>("XObject"); pXObject->SetNewFor<CPDF_Reference>(sImageAlias, @@ -1845,13 +1845,13 @@ void CPDFSDK_AppStream::Write(const ByteString& sAPType, const ByteString& sContents, const ByteString& sAPState) { - CPDF_Dictionary* pParentDict; + RetainPtr<CPDF_Dictionary> pParentDict; ByteString key; if (sAPState.IsEmpty()) { pParentDict = dict_.Get(); key = sAPType; } else { - pParentDict = GetOrCreateDict(dict_.Get(), sAPType); + pParentDict = dict_->GetOrCreateDictFor(sAPType); key = sAPState; }
diff --git a/fpdfsdk/cpdfsdk_baannot.cpp b/fpdfsdk/cpdfsdk_baannot.cpp index b3d9779..1dc685c 100644 --- a/fpdfsdk/cpdfsdk_baannot.cpp +++ b/fpdfsdk/cpdfsdk_baannot.cpp
@@ -53,7 +53,7 @@ } CPDF_Dictionary* CPDFSDK_BAAnnot::GetAPDict() const { - return GetOrCreateDict(GetAnnotDict(), pdfium::annotation::kAP); + return GetAnnotDict()->GetOrCreateDictFor(pdfium::annotation::kAP).Get(); } void CPDFSDK_BAAnnot::ClearCachedAnnotAP() { @@ -117,14 +117,14 @@ } void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) { + CPDF_Dictionary* pAnnotDict = GetAnnotDict(); RetainPtr<CPDF_Array> pBorder = - GetAnnotDict()->GetMutableArrayFor(pdfium::annotation::kBorder); + pAnnotDict->GetMutableArrayFor(pdfium::annotation::kBorder); if (pBorder) { pBorder->SetNewAt<CPDF_Number>(2, nWidth); - } else { - CPDF_Dictionary* pBSDict = GetOrCreateDict(GetAnnotDict(), "BS"); - pBSDict->SetNewFor<CPDF_Number>("W", nWidth); + return; } + pAnnotDict->GetOrCreateDictFor("BS")->SetNewFor<CPDF_Number>("W", nWidth); } int CPDFSDK_BAAnnot::GetBorderWidth() const { @@ -141,7 +141,7 @@ } void CPDFSDK_BAAnnot::SetBorderStyle(BorderStyle nStyle) { - CPDF_Dictionary* pBSDict = GetOrCreateDict(GetAnnotDict(), "BS"); + RetainPtr<CPDF_Dictionary> pBSDict = GetAnnotDict()->GetOrCreateDictFor("BS"); const char* name = nullptr; switch (nStyle) { case BorderStyle::kSolid:
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp index fce9b3e..3b63f45 100644 --- a/fpdfsdk/fpdf_annot.cpp +++ b/fpdfsdk/fpdf_annot.cpp
@@ -356,8 +356,8 @@ auto pNewAnnot = std::make_unique<CPDF_AnnotContext>( pDict.Get(), IPDFPageFromFPDFPage(page)); - CPDF_Array* pAnnotList = - GetOrCreateArray(pPage->GetMutableDict().Get(), "Annots"); + RetainPtr<CPDF_Array> pAnnotList = + pPage->GetMutableDict()->GetOrCreateArrayFor("Annots"); pAnnotList->Append(pDict); // Caller takes ownership. @@ -502,7 +502,7 @@ RetainPtr<CPDF_Dictionary> annot_dict = GetMutableAnnotDictFromFPDFAnnotation(annot); - CPDF_Array* inklist = GetOrCreateArray(annot_dict.Get(), "InkList"); + RetainPtr<CPDF_Array> inklist = annot_dict->GetOrCreateArrayFor("InkList"); FX_SAFE_SIZE_T safe_ink_size = inklist->size(); safe_ink_size += 1; if (!safe_ink_size.IsValid<int32_t>())
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp index 7025581..fdcec66 100644 --- a/fpdfsdk/fpdf_flatten.cpp +++ b/fpdfsdk/fpdf_flatten.cpp
@@ -295,11 +295,11 @@ pPageDict->SetRectFor(pdfium::page_object::kMediaBox, rcOriginalMB); pPageDict->SetRectFor(pdfium::page_object::kCropBox, rcOriginalCB); - CPDF_Dictionary* pRes = - GetOrCreateDict(pPageDict.Get(), pdfium::page_object::kResources); + RetainPtr<CPDF_Dictionary> pRes = + pPageDict->GetOrCreateDictFor(pdfium::page_object::kResources); CPDF_Stream* pNewXObject = pDocument->NewIndirect<CPDF_Stream>( nullptr, 0, pDocument->New<CPDF_Dictionary>()); - CPDF_Dictionary* pPageXObject = GetOrCreateDict(pRes, "XObject"); + RetainPtr<CPDF_Dictionary> pPageXObject = pRes->GetOrCreateDictFor("XObject"); ByteString key; if (!ObjectArray.empty()) { @@ -392,7 +392,8 @@ pObjDict->SetNewFor<CPDF_Name>("Subtype", "Form"); } - CPDF_Dictionary* pXObject = GetOrCreateDict(pNewXORes, "XObject"); + RetainPtr<CPDF_Dictionary> pXObject = + pNewXORes->GetOrCreateDictFor("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 50f0390..50a37cd 100644 --- a/fpdfsdk/fpdf_ppo.cpp +++ b/fpdfsdk/fpdf_ppo.cpp
@@ -668,9 +668,9 @@ const ByteString& bsContent) { DCHECK(pDestPageDict); - CPDF_Dictionary* pRes = - GetOrCreateDict(pDestPageDict, pdfium::page_object::kResources); - CPDF_Dictionary* pPageXObject = GetOrCreateDict(pRes, "XObject"); + RetainPtr<CPDF_Dictionary> pRes = + pDestPageDict->GetOrCreateDictFor(pdfium::page_object::kResources); + RetainPtr<CPDF_Dictionary> pPageXObject = pRes->GetOrCreateDictFor("XObject"); for (auto& it : m_XObjectNameToNumberMap) pPageXObject->SetNewFor<CPDF_Reference>(it.first, dest(), it.second);