diff options
author | Artem Strygin <art-snake@yandex-team.ru> | 2018-06-11 18:19:57 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-06-11 18:19:57 +0000 |
commit | fb72726e51bfd0c7bfc61c9b354e2b60f46adac5 (patch) | |
tree | b2a763c74a07b081a4b176c18c42569e377d6fc8 /core/fpdfapi/parser | |
parent | 5e873f5ce8e407c97e966b9708d2560e908112d3 (diff) | |
download | pdfium-fb72726e51bfd0c7bfc61c9b354e2b60f46adac5.tar.xz |
Implement CPDF_Object::MakeReference method.chromium/3456
Change-Id: I153747ef587a184eaef58ff09dbf8f214c9ddfb3
Reviewed-on: https://pdfium-review.googlesource.com/17230
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Art Snake <art-snake@yandex-team.ru>
Diffstat (limited to 'core/fpdfapi/parser')
-rw-r--r-- | core/fpdfapi/parser/cpdf_array.cpp | 2 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_dictionary.cpp | 2 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_document.cpp | 25 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_object.cpp | 10 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_object.h | 6 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_object_unittest.cpp | 27 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_reference.cpp | 8 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_reference.h | 2 |
8 files changed, 66 insertions, 16 deletions
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp index a5361fbbb9..d53476d1c2 100644 --- a/core/fpdfapi/parser/cpdf_array.cpp +++ b/core/fpdfapi/parser/cpdf_array.cpp @@ -191,7 +191,7 @@ void CPDF_Array::ConvertToIndirectObjectAt(size_t i, return; CPDF_Object* pNew = pHolder->AddIndirectObject(std::move(m_Objects[i])); - m_Objects[i] = pdfium::MakeUnique<CPDF_Reference>(pHolder, pNew->GetObjNum()); + m_Objects[i] = pNew->MakeReference(pHolder); } CPDF_Object* CPDF_Array::SetAt(size_t i, std::unique_ptr<CPDF_Object> pObj) { diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp index c6127fa344..071461b756 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.cpp +++ b/core/fpdfapi/parser/cpdf_dictionary.cpp @@ -224,7 +224,7 @@ void CPDF_Dictionary::ConvertToIndirectObjectFor( return; CPDF_Object* pObj = pHolder->AddIndirectObject(std::move(it->second)); - it->second = pdfium::MakeUnique<CPDF_Reference>(pHolder, pObj->GetObjNum()); + it->second = pObj->MakeReference(pHolder); } std::unique_ptr<CPDF_Object> CPDF_Dictionary::RemoveFor(const ByteString& key) { diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp index 59927bc250..b163cafbbb 100644 --- a/core/fpdfapi/parser/cpdf_document.cpp +++ b/core/fpdfapi/parser/cpdf_document.cpp @@ -513,7 +513,7 @@ void CPDF_Document::CreateNewDoc() { pPages->SetNewFor<CPDF_Name>("Type", "Pages"); pPages->SetNewFor<CPDF_Number>("Count", 0); pPages->SetNewFor<CPDF_Array>("Kids"); - m_pRootDict->SetNewFor<CPDF_Reference>("Pages", this, pPages->GetObjNum()); + m_pRootDict->SetFor("Pages", pPages->MakeReference(this)); m_pInfoDict = NewIndirect<CPDF_Dictionary>(); } @@ -545,9 +545,8 @@ bool CPDF_Document::InsertDeletePDFPage(CPDF_Dictionary* pPages, continue; } if (bInsert) { - pKidList->InsertNewAt<CPDF_Reference>(i, this, pPageDict->GetObjNum()); - pPageDict->SetNewFor<CPDF_Reference>("Parent", this, - pPages->GetObjNum()); + pKidList->InsertAt(i, pPageDict->MakeReference(this)); + pPageDict->SetFor("Parent", pPages->MakeReference(this)); } else { pKidList->RemoveAt(i); } @@ -589,9 +588,9 @@ bool CPDF_Document::InsertNewPage(int iPage, CPDF_Dictionary* pPageDict) { CPDF_Array* pPagesList = pPages->GetArrayFor("Kids"); if (!pPagesList) pPagesList = pPages->SetNewFor<CPDF_Array>("Kids"); - pPagesList->AddNew<CPDF_Reference>(this, pPageDict->GetObjNum()); + pPagesList->Add(pPageDict->MakeReference(this)); pPages->SetNewFor<CPDF_Number>("Count", nPages + 1); - pPageDict->SetNewFor<CPDF_Reference>("Parent", this, pPages->GetObjNum()); + pPageDict->SetFor("Parent", pPages->MakeReference(this)); ResetTraversal(); } else { std::set<CPDF_Dictionary*> stack = {pPages}; @@ -647,8 +646,7 @@ size_t CPDF_Document::CalculateEncodingDict(int charset, ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); pArray->AddNew<CPDF_Name>(name.IsEmpty() ? ".notdef" : name); } - pBaseDict->SetNewFor<CPDF_Reference>("Encoding", this, - pEncodingDict->GetObjNum()); + pBaseDict->SetFor("Encoding", pEncodingDict->MakeReference(this)); return i; } @@ -715,7 +713,7 @@ CPDF_Dictionary* CPDF_Document::ProcessbCJK( pCIDSysInfo->SetNewFor<CPDF_Number>("Supplement", supplement); CPDF_Array* pArray = pBaseDict->SetNewFor<CPDF_Array>("DescendantFonts"); - pArray->AddNew<CPDF_Reference>(this, pFontDict->GetObjNum()); + pArray->Add(pFontDict->MakeReference(this)); return pFontDict; } @@ -796,8 +794,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) { CPDF_Dictionary* pFontDesc = ToDictionary(AddIndirectObject( CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(), pFont->GetDescent(), std::move(pBBox), nStemV))); - pFontDict->SetNewFor<CPDF_Reference>("FontDescriptor", this, - pFontDesc->GetObjNum()); + pFontDict->SetFor("FontDescriptor", pFontDesc->MakeReference(this)); return LoadFont(pBaseDict); } @@ -889,9 +886,9 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend, std::move(pBBox), pLogFont->lfWeight / 5); pFontDesc->SetNewFor<CPDF_Number>("CapHeight", capheight); - pFontDict->SetNewFor<CPDF_Reference>( - "FontDescriptor", this, - AddIndirectObject(std::move(pFontDesc))->GetObjNum()); + pFontDict->SetFor( + "FontDescriptor", + AddIndirectObject(std::move(pFontDesc))->MakeReference(this)); hFont = SelectObject(hDC, hFont); DeleteObject(hFont); DeleteDC(hDC); diff --git a/core/fpdfapi/parser/cpdf_object.cpp b/core/fpdfapi/parser/cpdf_object.cpp index 8190d3429f..6fedd25242 100644 --- a/core/fpdfapi/parser/cpdf_object.cpp +++ b/core/fpdfapi/parser/cpdf_object.cpp @@ -12,6 +12,7 @@ #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" #include "core/fpdfapi/parser/cpdf_parser.h" +#include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "core/fxcrt/fx_string.h" #include "third_party/base/logging.h" @@ -170,3 +171,12 @@ CPDF_String* CPDF_Object::AsString() { const CPDF_String* CPDF_Object::AsString() const { return nullptr; } + +std::unique_ptr<CPDF_Object> CPDF_Object::MakeReference( + CPDF_IndirectObjectHolder* holder) const { + if (IsInline()) { + NOTREACHED(); + return nullptr; + } + return pdfium::MakeUnique<CPDF_Reference>(holder, GetObjNum()); +} diff --git a/core/fpdfapi/parser/cpdf_object.h b/core/fpdfapi/parser/cpdf_object.h index 21eec62b0d..5ff028e9e0 100644 --- a/core/fpdfapi/parser/cpdf_object.h +++ b/core/fpdfapi/parser/cpdf_object.h @@ -17,6 +17,7 @@ class CPDF_Array; class CPDF_Boolean; class CPDF_Dictionary; +class CPDF_IndirectObjectHolder; class CPDF_Name; class CPDF_Null; class CPDF_Number; @@ -106,6 +107,11 @@ class CPDF_Object { bool bDirect, std::set<const CPDF_Object*>* pVisited) const; + // Return a reference to itself. + // The object must be direct (!IsInlined). + virtual std::unique_ptr<CPDF_Object> MakeReference( + CPDF_IndirectObjectHolder* holder) const; + protected: CPDF_Object() : m_ObjNum(0), m_GenNum(0) {} diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp index 856dd0ac3b..78a0af7299 100644 --- a/core/fpdfapi/parser/cpdf_object_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp @@ -393,6 +393,18 @@ TEST_F(PDFObjectsTest, IsTypeAndAsType) { } } +TEST_F(PDFObjectsTest, MakeReferenceGeneric) { + auto original_obj = pdfium::MakeUnique<CPDF_Null>(); + original_obj->SetObjNum(42); + ASSERT_FALSE(original_obj->IsInline()); + + auto ref_obj = original_obj->MakeReference(m_ObjHolder.get()); + + ASSERT_TRUE(ref_obj->IsReference()); + EXPECT_EQ(original_obj->GetObjNum(), + ToReference(ref_obj.get())->GetRefObjNum()); +} + TEST(PDFArrayTest, GetMatrix) { float elems[][6] = {{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, {1, 2, 3, 4, 5, 6}, @@ -971,3 +983,18 @@ TEST(PDFDictionaryTest, ExtractObjectOnRemove) { extracted_object = dict->RemoveFor("non_exists_object"); EXPECT_FALSE(extracted_object); } + +TEST(PDFRefernceTest, MakeReferenceToReference) { + auto obj_holder = pdfium::MakeUnique<CPDF_IndirectObjectHolder>(); + auto original_ref = pdfium::MakeUnique<CPDF_Reference>(obj_holder.get(), 42); + original_ref->SetObjNum(1952); + ASSERT_FALSE(original_ref->IsInline()); + + auto ref_obj = original_ref->MakeReference(obj_holder.get()); + + ASSERT_TRUE(ref_obj->IsReference()); + // We do not allow reference to reference. + // New reference should have same RefObjNum. + EXPECT_EQ(original_ref->GetRefObjNum(), + ToReference(ref_obj.get())->GetRefObjNum()); +} diff --git a/core/fpdfapi/parser/cpdf_reference.cpp b/core/fpdfapi/parser/cpdf_reference.cpp index 3f45a96c6b..0f3b7627d6 100644 --- a/core/fpdfapi/parser/cpdf_reference.cpp +++ b/core/fpdfapi/parser/cpdf_reference.cpp @@ -103,3 +103,11 @@ bool CPDF_Reference::WriteTo(IFX_ArchiveStream* archive) const { return archive->WriteString(" ") && archive->WriteDWord(GetRefObjNum()) && archive->WriteString(" 0 R "); } + +std::unique_ptr<CPDF_Object> CPDF_Reference::MakeReference( + CPDF_IndirectObjectHolder* holder) const { + ASSERT(holder == m_pObjList.Get()); + // Do not allow reference to reference, just create other reference for same + // object. + return pdfium::MakeUnique<CPDF_Reference>(holder, GetRefObjNum()); +} diff --git a/core/fpdfapi/parser/cpdf_reference.h b/core/fpdfapi/parser/cpdf_reference.h index 4cfb5c26e3..d1e0a07e4b 100644 --- a/core/fpdfapi/parser/cpdf_reference.h +++ b/core/fpdfapi/parser/cpdf_reference.h @@ -34,6 +34,8 @@ class CPDF_Reference : public CPDF_Object { CPDF_Reference* AsReference() override; const CPDF_Reference* AsReference() const override; bool WriteTo(IFX_ArchiveStream* archive) const override; + std::unique_ptr<CPDF_Object> MakeReference( + CPDF_IndirectObjectHolder* holder) const override; CPDF_IndirectObjectHolder* GetObjList() const { return m_pObjList.Get(); } uint32_t GetRefObjNum() const { return m_RefObjNum; } |