summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser
diff options
context:
space:
mode:
authorArtem Strygin <art-snake@yandex-team.ru>2018-06-11 18:19:57 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-06-11 18:19:57 +0000
commitfb72726e51bfd0c7bfc61c9b354e2b60f46adac5 (patch)
treeb2a763c74a07b081a4b176c18c42569e377d6fc8 /core/fpdfapi/parser
parent5e873f5ce8e407c97e966b9708d2560e908112d3 (diff)
downloadpdfium-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.cpp2
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.cpp2
-rw-r--r--core/fpdfapi/parser/cpdf_document.cpp25
-rw-r--r--core/fpdfapi/parser/cpdf_object.cpp10
-rw-r--r--core/fpdfapi/parser/cpdf_object.h6
-rw-r--r--core/fpdfapi/parser/cpdf_object_unittest.cpp27
-rw-r--r--core/fpdfapi/parser/cpdf_reference.cpp8
-rw-r--r--core/fpdfapi/parser/cpdf_reference.h2
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; }