Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: core/fpdfapi/parser/cpdf_object_unittest.cpp

Issue 2510223002: Make CPDF_Dictionary use unique pointers. (Closed)
Patch Set: rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfapi/parser/cpdf_document_unittest.cpp ('k') | core/fpdfapi/parser/cpdf_parser.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 PDFium Authors. All rights reserved. 1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/fpdfapi/parser/cpdf_array.h" 5 #include "core/fpdfapi/parser/cpdf_array.h"
6 #include "core/fpdfapi/parser/cpdf_boolean.h" 6 #include "core/fpdfapi/parser/cpdf_boolean.h"
7 #include "core/fpdfapi/parser/cpdf_dictionary.h" 7 #include "core/fpdfapi/parser/cpdf_dictionary.h"
8 #include "core/fpdfapi/parser/cpdf_name.h" 8 #include "core/fpdfapi/parser/cpdf_name.h"
9 #include "core/fpdfapi/parser/cpdf_null.h" 9 #include "core/fpdfapi/parser/cpdf_null.h"
10 #include "core/fpdfapi/parser/cpdf_number.h" 10 #include "core/fpdfapi/parser/cpdf_number.h"
11 #include "core/fpdfapi/parser/cpdf_reference.h" 11 #include "core/fpdfapi/parser/cpdf_reference.h"
12 #include "core/fpdfapi/parser/cpdf_stream.h" 12 #include "core/fpdfapi/parser/cpdf_stream.h"
13 #include "core/fpdfapi/parser/cpdf_string.h" 13 #include "core/fpdfapi/parser/cpdf_string.h"
14 14
15 #include <memory> 15 #include <memory>
16 #include <string> 16 #include <string>
17 #include <utility>
17 #include <vector> 18 #include <vector>
18 19
19 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" 20 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
20 #include "core/fxcrt/fx_basic.h" 21 #include "core/fxcrt/fx_basic.h"
21 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
22 23
23 namespace { 24 namespace {
24 25
25 void TestArrayAccessors(const CPDF_Array* arr, 26 void TestArrayAccessors(const CPDF_Array* arr,
26 size_t index, 27 size_t index,
(...skipping 19 matching lines...) Expand all
46 public: 47 public:
47 void SetUp() override { 48 void SetUp() override {
48 // Initialize different kinds of objects. 49 // Initialize different kinds of objects.
49 // Boolean objects. 50 // Boolean objects.
50 CPDF_Boolean* boolean_false_obj = new CPDF_Boolean(false); 51 CPDF_Boolean* boolean_false_obj = new CPDF_Boolean(false);
51 CPDF_Boolean* boolean_true_obj = new CPDF_Boolean(true); 52 CPDF_Boolean* boolean_true_obj = new CPDF_Boolean(true);
52 // Number objects. 53 // Number objects.
53 CPDF_Number* number_int_obj = new CPDF_Number(1245); 54 CPDF_Number* number_int_obj = new CPDF_Number(1245);
54 CPDF_Number* number_float_obj = new CPDF_Number(9.00345f); 55 CPDF_Number* number_float_obj = new CPDF_Number(9.00345f);
55 // String objects. 56 // String objects.
56 CPDF_String* str_reg_obj = new CPDF_String(L"A simple test"); 57 CPDF_String* str_reg_obj = new CPDF_String(nullptr, L"A simple test");
57 CPDF_String* str_spec_obj = new CPDF_String(L"\t\n"); 58 CPDF_String* str_spec_obj = new CPDF_String(nullptr, L"\t\n");
58 // Name object. 59 // Name object.
59 CPDF_Name* name_obj = new CPDF_Name(nullptr, "space"); 60 CPDF_Name* name_obj = new CPDF_Name(nullptr, "space");
60 // Array object. 61 // Array object.
61 m_ArrayObj = new CPDF_Array; 62 m_ArrayObj = new CPDF_Array;
62 m_ArrayObj->InsertNewAt<CPDF_Number>(0, 8902); 63 m_ArrayObj->InsertNewAt<CPDF_Number>(0, 8902);
63 m_ArrayObj->InsertNewAt<CPDF_Name>(1, "address"); 64 m_ArrayObj->InsertNewAt<CPDF_Name>(1, "address");
64 // Dictionary object. 65 // Dictionary object.
65 m_DictObj = new CPDF_Dictionary(); 66 m_DictObj = new CPDF_Dictionary();
66 m_DictObj->SetFor("bool", new CPDF_Boolean(false)); 67 m_DictObj->SetNewFor<CPDF_Boolean>("bool", false);
67 m_DictObj->SetFor("num", new CPDF_Number(0.23f)); 68 m_DictObj->SetNewFor<CPDF_Number>("num", 0.23f);
68 // Stream object. 69 // Stream object.
69 const char content[] = "abcdefghijklmnopqrstuvwxyz"; 70 const char content[] = "abcdefghijklmnopqrstuvwxyz";
70 size_t buf_len = FX_ArraySize(content); 71 size_t buf_len = FX_ArraySize(content);
71 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_len)); 72 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_len));
72 memcpy(buf, content, buf_len); 73 memcpy(buf, content, buf_len);
73 m_StreamDictObj = new CPDF_Dictionary(); 74 m_StreamDictObj = new CPDF_Dictionary();
74 m_StreamDictObj->SetFor("key1", new CPDF_String(L" test dict")); 75 m_StreamDictObj->SetNewFor<CPDF_String>("key1", L" test dict");
75 m_StreamDictObj->SetFor("key2", new CPDF_Number(-1)); 76 m_StreamDictObj->SetNewFor<CPDF_Number>("key2", -1);
76 CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj); 77 CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj);
77 // Null Object. 78 // Null Object.
78 CPDF_Null* null_obj = new CPDF_Null; 79 CPDF_Null* null_obj = new CPDF_Null;
79 // All direct objects. 80 // All direct objects.
80 CPDF_Object* objs[] = {boolean_false_obj, boolean_true_obj, number_int_obj, 81 CPDF_Object* objs[] = {boolean_false_obj, boolean_true_obj, number_int_obj,
81 number_float_obj, str_reg_obj, str_spec_obj, 82 number_float_obj, str_reg_obj, str_spec_obj,
82 name_obj, m_ArrayObj, m_DictObj, 83 name_obj, m_ArrayObj, m_DictObj,
83 stream_obj, null_obj}; 84 stream_obj, null_obj};
84 m_DirectObjTypes = { 85 m_DirectObjTypes = {
85 CPDF_Object::BOOLEAN, CPDF_Object::BOOLEAN, CPDF_Object::NUMBER, 86 CPDF_Object::BOOLEAN, CPDF_Object::BOOLEAN, CPDF_Object::NUMBER,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 } 130 }
130 return true; 131 return true;
131 } 132 }
132 case CPDF_Object::DICTIONARY: { 133 case CPDF_Object::DICTIONARY: {
133 const CPDF_Dictionary* dict1 = obj1->AsDictionary(); 134 const CPDF_Dictionary* dict1 = obj1->AsDictionary();
134 const CPDF_Dictionary* dict2 = obj2->AsDictionary(); 135 const CPDF_Dictionary* dict2 = obj2->AsDictionary();
135 if (dict1->GetCount() != dict2->GetCount()) 136 if (dict1->GetCount() != dict2->GetCount())
136 return false; 137 return false;
137 for (CPDF_Dictionary::const_iterator it = dict1->begin(); 138 for (CPDF_Dictionary::const_iterator it = dict1->begin();
138 it != dict1->end(); ++it) { 139 it != dict1->end(); ++it) {
139 if (!Equal(it->second, dict2->GetObjectFor(it->first))) 140 if (!Equal(it->second.get(), dict2->GetObjectFor(it->first)))
140 return false; 141 return false;
141 } 142 }
142 return true; 143 return true;
143 } 144 }
144 case CPDF_Object::NULLOBJ: 145 case CPDF_Object::NULLOBJ:
145 return true; 146 return true;
146 case CPDF_Object::STREAM: { 147 case CPDF_Object::STREAM: {
147 const CPDF_Stream* stream1 = obj1->AsStream(); 148 const CPDF_Stream* stream1 = obj1->AsStream();
148 const CPDF_Stream* stream2 = obj2->AsStream(); 149 const CPDF_Stream* stream2 = obj2->AsStream();
149 if (!stream1->GetDict() && !stream2->GetDict()) 150 if (!stream1->GetDict() && !stream2->GetDict())
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 // Dictionary array. 549 // Dictionary array.
549 CPDF_Dictionary* vals[3]; 550 CPDF_Dictionary* vals[3];
550 auto arr = pdfium::MakeUnique<CPDF_Array>(); 551 auto arr = pdfium::MakeUnique<CPDF_Array>();
551 for (size_t i = 0; i < 3; ++i) { 552 for (size_t i = 0; i < 3; ++i) {
552 vals[i] = arr->AddNew<CPDF_Dictionary>(); 553 vals[i] = arr->AddNew<CPDF_Dictionary>();
553 for (size_t j = 0; j < 3; ++j) { 554 for (size_t j = 0; j < 3; ++j) {
554 std::string key("key"); 555 std::string key("key");
555 char buf[33]; 556 char buf[33];
556 key.append(FXSYS_itoa(j, buf, 10)); 557 key.append(FXSYS_itoa(j, buf, 10));
557 int value = j + 200; 558 int value = j + 200;
558 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); 559 vals[i]->SetNewFor<CPDF_Number>(key.c_str(), value);
559 } 560 }
560 } 561 }
561 for (size_t i = 0; i < 3; ++i) { 562 for (size_t i = 0; i < 3; ++i) {
562 TestArrayAccessors(arr.get(), i, // Array and index. 563 TestArrayAccessors(arr.get(), i, // Array and index.
563 "", // String value. 564 "", // String value.
564 nullptr, // Const string value. 565 nullptr, // Const string value.
565 0, // Integer value. 566 0, // Integer value.
566 0, // Float value. 567 0, // Float value.
567 nullptr, // Array value. 568 nullptr, // Array value.
568 vals[i], // Dictionary value. 569 vals[i], // Dictionary value.
569 nullptr); // Stream value. 570 nullptr); // Stream value.
570 } 571 }
571 } 572 }
572 { 573 {
573 // Stream array. 574 // Stream array.
574 CPDF_Dictionary* vals[3]; 575 CPDF_Dictionary* vals[3];
575 CPDF_Stream* stream_vals[3]; 576 CPDF_Stream* stream_vals[3];
576 auto arr = pdfium::MakeUnique<CPDF_Array>(); 577 auto arr = pdfium::MakeUnique<CPDF_Array>();
577 for (size_t i = 0; i < 3; ++i) { 578 for (size_t i = 0; i < 3; ++i) {
578 vals[i] = new CPDF_Dictionary(); 579 vals[i] = new CPDF_Dictionary();
579 for (size_t j = 0; j < 3; ++j) { 580 for (size_t j = 0; j < 3; ++j) {
580 std::string key("key"); 581 std::string key("key");
581 char buf[33]; 582 char buf[33];
582 key.append(FXSYS_itoa(j, buf, 10)); 583 key.append(FXSYS_itoa(j, buf, 10));
583 int value = j + 200; 584 int value = j + 200;
584 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); 585 vals[i]->SetNewFor<CPDF_Number>(key.c_str(), value);
585 } 586 }
586 uint8_t content[] = "content: this is a stream"; 587 uint8_t content[] = "content: this is a stream";
587 size_t data_size = FX_ArraySize(content); 588 size_t data_size = FX_ArraySize(content);
588 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size)); 589 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size));
589 memcpy(data, content, data_size); 590 memcpy(data, content, data_size);
590 stream_vals[i] = arr->AddNew<CPDF_Stream>(data, data_size, vals[i]); 591 stream_vals[i] = arr->AddNew<CPDF_Stream>(data, data_size, vals[i]);
591 } 592 }
592 for (size_t i = 0; i < 3; ++i) { 593 for (size_t i = 0; i < 3; ++i) {
593 TestArrayAccessors(arr.get(), i, // Array and index. 594 TestArrayAccessors(arr.get(), i, // Array and index.
594 "", // String value. 595 "", // String value.
(...skipping 18 matching lines...) Expand all
613 arr->InsertNewAt<CPDF_String>(7, "It is a test!", false); 614 arr->InsertNewAt<CPDF_String>(7, "It is a test!", false);
614 arr->InsertNewAt<CPDF_Name>(8, "NAME"); 615 arr->InsertNewAt<CPDF_Name>(8, "NAME");
615 arr->InsertNewAt<CPDF_Name>(9, "test"); 616 arr->InsertNewAt<CPDF_Name>(9, "test");
616 arr->InsertNewAt<CPDF_Null>(10); 617 arr->InsertNewAt<CPDF_Null>(10);
617 618
618 CPDF_Array* arr_val = arr->InsertNewAt<CPDF_Array>(11); 619 CPDF_Array* arr_val = arr->InsertNewAt<CPDF_Array>(11);
619 arr_val->AddNew<CPDF_Number>(1); 620 arr_val->AddNew<CPDF_Number>(1);
620 arr_val->AddNew<CPDF_Number>(2); 621 arr_val->AddNew<CPDF_Number>(2);
621 622
622 CPDF_Dictionary* dict_val = arr->InsertNewAt<CPDF_Dictionary>(12); 623 CPDF_Dictionary* dict_val = arr->InsertNewAt<CPDF_Dictionary>(12);
623 dict_val->SetFor("key1", new CPDF_String(nullptr, "Linda", false)); 624 dict_val->SetNewFor<CPDF_String>("key1", "Linda", false);
624 dict_val->SetFor("key2", new CPDF_String(nullptr, "Zoe", false)); 625 dict_val->SetNewFor<CPDF_String>("key2", "Zoe", false);
625 626
626 CPDF_Dictionary* stream_dict = new CPDF_Dictionary(); 627 CPDF_Dictionary* stream_dict = new CPDF_Dictionary();
627 stream_dict->SetFor("key1", new CPDF_String(nullptr, "John", false)); 628 stream_dict->SetNewFor<CPDF_String>("key1", "John", false);
628 stream_dict->SetFor("key2", new CPDF_String(nullptr, "King", false)); 629 stream_dict->SetNewFor<CPDF_String>("key2", "King", false);
629 uint8_t data[] = "A stream for test"; 630 uint8_t data[] = "A stream for test";
630 // The data buffer will be owned by stream object, so it needs to be 631 // The data buffer will be owned by stream object, so it needs to be
631 // dynamically allocated. 632 // dynamically allocated.
632 size_t buf_size = sizeof(data); 633 size_t buf_size = sizeof(data);
633 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_size)); 634 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_size));
634 memcpy(buf, data, buf_size); 635 memcpy(buf, data, buf_size);
635 CPDF_Stream* stream_val = 636 CPDF_Stream* stream_val =
636 arr->InsertNewAt<CPDF_Stream>(13, buf, buf_size, stream_dict); 637 arr->InsertNewAt<CPDF_Stream>(13, buf, buf_size, stream_dict);
637 const char* const expected_str[] = { 638 const char* const expected_str[] = {
638 "true", "false", "0", "-1234", "2345", "0.05", "", 639 "true", "false", "0", "-1234", "2345", "0.05", "",
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 EXPECT_TRUE(pRef->IsReference()); 772 EXPECT_TRUE(pRef->IsReference());
772 EXPECT_TRUE(pNum->IsNumber()); 773 EXPECT_TRUE(pNum->IsNumber());
773 EXPECT_NE(pObj, pRef); 774 EXPECT_NE(pObj, pRef);
774 EXPECT_EQ(pObj, pNum); 775 EXPECT_EQ(pObj, pNum);
775 EXPECT_EQ(42, array->GetIntegerAt(0)); 776 EXPECT_EQ(42, array->GetIntegerAt(0));
776 } 777 }
777 778
778 TEST(PDFDictionaryTest, CloneDirectObject) { 779 TEST(PDFDictionaryTest, CloneDirectObject) {
779 CPDF_IndirectObjectHolder objects_holder; 780 CPDF_IndirectObjectHolder objects_holder;
780 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary()); 781 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary());
781 dict->SetReferenceFor("foo", &objects_holder, 1234); 782 dict->SetNewFor<CPDF_Reference>("foo", &objects_holder, 1234);
782 ASSERT_EQ(1U, dict->GetCount()); 783 ASSERT_EQ(1U, dict->GetCount());
783 CPDF_Object* obj = dict->GetObjectFor("foo"); 784 CPDF_Object* obj = dict->GetObjectFor("foo");
784 ASSERT_TRUE(obj); 785 ASSERT_TRUE(obj);
785 EXPECT_TRUE(obj->IsReference()); 786 EXPECT_TRUE(obj->IsReference());
786 787
787 std::unique_ptr<CPDF_Object> cloned_dict_object = dict->CloneDirectObject(); 788 std::unique_ptr<CPDF_Object> cloned_dict_object = dict->CloneDirectObject();
788 ASSERT_TRUE(cloned_dict_object); 789 ASSERT_TRUE(cloned_dict_object);
789 ASSERT_TRUE(cloned_dict_object->IsDictionary()); 790 ASSERT_TRUE(cloned_dict_object->IsDictionary());
790 791
791 std::unique_ptr<CPDF_Dictionary> cloned_dict = 792 std::unique_ptr<CPDF_Dictionary> cloned_dict =
792 ToDictionary(std::move(cloned_dict_object)); 793 ToDictionary(std::move(cloned_dict_object));
793 ASSERT_EQ(1U, cloned_dict->GetCount()); 794 ASSERT_EQ(1U, cloned_dict->GetCount());
794 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo"); 795 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo");
795 EXPECT_FALSE(cloned_obj); 796 EXPECT_FALSE(cloned_obj);
796 } 797 }
797 798
798 TEST(PDFObjectTest, CloneCheckLoop) { 799 TEST(PDFObjectTest, CloneCheckLoop) {
799 { 800 {
800 // Create a dictionary/array pair with a reference loop. 801 // Create a dictionary/array pair with a reference loop. It takes
802 // some work to do this nowadays, in particular we need the
803 // anti-pattern pdfium::WrapUnique(arr.get()).
801 auto arr_obj = pdfium::MakeUnique<CPDF_Array>(); 804 auto arr_obj = pdfium::MakeUnique<CPDF_Array>();
802 CPDF_Dictionary* dict_obj = arr_obj->InsertNewAt<CPDF_Dictionary>(0); 805 CPDF_Dictionary* dict_obj = arr_obj->InsertNewAt<CPDF_Dictionary>(0);
803 dict_obj->SetFor("arr", arr_obj.get()); 806 dict_obj->SetFor("arr", pdfium::WrapUnique(arr_obj.get()));
804 // Clone this object to see whether stack overflow will be triggered. 807 // Clone this object to see whether stack overflow will be triggered.
805 std::unique_ptr<CPDF_Array> cloned_array = ToArray(arr_obj->Clone()); 808 std::unique_ptr<CPDF_Array> cloned_array = ToArray(arr_obj->Clone());
806 // Cloned object should be the same as the original. 809 // Cloned object should be the same as the original.
807 ASSERT_TRUE(cloned_array); 810 ASSERT_TRUE(cloned_array);
808 EXPECT_EQ(1u, cloned_array->GetCount()); 811 EXPECT_EQ(1u, cloned_array->GetCount());
809 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0); 812 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0);
810 ASSERT_TRUE(cloned_dict); 813 ASSERT_TRUE(cloned_dict);
811 ASSERT_TRUE(cloned_dict->IsDictionary()); 814 ASSERT_TRUE(cloned_dict->IsDictionary());
812 // Recursively referenced object is not cloned. 815 // Recursively referenced object is not cloned.
813 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr")); 816 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr"));
814 } 817 }
815 { 818 {
816 // Create a dictionary/stream pair with a reference loop. 819 // Create a dictionary/stream pair with a reference loop.
817 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); 820 auto dict_obj = pdfium::MakeUnique<CPDF_Dictionary>();
818 std::unique_ptr<CPDF_Stream> stream_obj( 821 CPDF_Stream* stream_obj =
819 new CPDF_Stream(nullptr, 0, dict_obj)); 822 dict_obj->SetNewFor<CPDF_Stream>("stream", nullptr, 0, dict_obj.get());
820 dict_obj->SetFor("stream", stream_obj.get());
821
822 // Clone this object to see whether stack overflow will be triggered. 823 // Clone this object to see whether stack overflow will be triggered.
823 std::unique_ptr<CPDF_Stream> cloned_stream = ToStream(stream_obj->Clone()); 824 std::unique_ptr<CPDF_Stream> cloned_stream = ToStream(stream_obj->Clone());
824 // Cloned object should be the same as the original. 825 // Cloned object should be the same as the original.
825 ASSERT_TRUE(cloned_stream); 826 ASSERT_TRUE(cloned_stream);
826 CPDF_Object* cloned_dict = cloned_stream->GetDict(); 827 CPDF_Object* cloned_dict = cloned_stream->GetDict();
827 ASSERT_TRUE(cloned_dict); 828 ASSERT_TRUE(cloned_dict);
828 ASSERT_TRUE(cloned_dict->IsDictionary()); 829 ASSERT_TRUE(cloned_dict->IsDictionary());
829 // Recursively referenced object is not cloned. 830 // Recursively referenced object is not cloned.
830 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("stream")); 831 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("stream"));
831 } 832 }
832 { 833 {
833 CPDF_IndirectObjectHolder objects_holder; 834 CPDF_IndirectObjectHolder objects_holder;
834 // Create an object with a reference loop. 835 // Create an object with a reference loop.
835 CPDF_Dictionary* dict_obj = objects_holder.NewIndirect<CPDF_Dictionary>(); 836 CPDF_Dictionary* dict_obj = objects_holder.NewIndirect<CPDF_Dictionary>();
836 std::unique_ptr<CPDF_Array> arr_obj = pdfium::MakeUnique<CPDF_Array>(); 837 std::unique_ptr<CPDF_Array> arr_obj = pdfium::MakeUnique<CPDF_Array>();
837 arr_obj->InsertNewAt<CPDF_Reference>(0, &objects_holder, 838 arr_obj->InsertNewAt<CPDF_Reference>(0, &objects_holder,
838 dict_obj->GetObjNum()); 839 dict_obj->GetObjNum());
839 CPDF_Object* elem0 = arr_obj->GetObjectAt(0); 840 CPDF_Object* elem0 = arr_obj->GetObjectAt(0);
840 dict_obj->SetFor("arr", arr_obj.release()); 841 dict_obj->SetFor("arr", std::move(arr_obj));
841 EXPECT_EQ(1u, dict_obj->GetObjNum()); 842 EXPECT_EQ(1u, dict_obj->GetObjNum());
842 ASSERT_TRUE(elem0); 843 ASSERT_TRUE(elem0);
843 ASSERT_TRUE(elem0->IsReference()); 844 ASSERT_TRUE(elem0->IsReference());
844 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum()); 845 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum());
845 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect()); 846 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect());
846 847
847 // Clone this object to see whether stack overflow will be triggered. 848 // Clone this object to see whether stack overflow will be triggered.
848 std::unique_ptr<CPDF_Dictionary> cloned_dict = 849 std::unique_ptr<CPDF_Dictionary> cloned_dict =
849 ToDictionary(dict_obj->CloneDirectObject()); 850 ToDictionary(dict_obj->CloneDirectObject());
850 // Cloned object should be the same as the original. 851 // Cloned object should be the same as the original.
851 ASSERT_TRUE(cloned_dict); 852 ASSERT_TRUE(cloned_dict);
852 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr"); 853 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr");
853 ASSERT_TRUE(cloned_arr); 854 ASSERT_TRUE(cloned_arr);
854 ASSERT_TRUE(cloned_arr->IsArray()); 855 ASSERT_TRUE(cloned_arr->IsArray());
855 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount()); 856 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount());
856 // Recursively referenced object is not cloned. 857 // Recursively referenced object is not cloned.
857 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0)); 858 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0));
858 } 859 }
859 } 860 }
860 861
861 TEST(PDFDictionaryTest, ConvertIndirect) { 862 TEST(PDFDictionaryTest, ConvertIndirect) {
862 CPDF_IndirectObjectHolder objects_holder; 863 CPDF_IndirectObjectHolder objects_holder;
863 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary); 864 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary);
864 CPDF_Object* pObj = new CPDF_Number(42); 865 CPDF_Object* pObj = dict->SetNewFor<CPDF_Number>("clams", 42);
865 dict->SetFor("clams", pObj);
866 dict->ConvertToIndirectObjectFor("clams", &objects_holder); 866 dict->ConvertToIndirectObjectFor("clams", &objects_holder);
867 CPDF_Object* pRef = dict->GetObjectFor("clams"); 867 CPDF_Object* pRef = dict->GetObjectFor("clams");
868 CPDF_Object* pNum = dict->GetDirectObjectFor("clams"); 868 CPDF_Object* pNum = dict->GetDirectObjectFor("clams");
869 EXPECT_TRUE(pRef->IsReference()); 869 EXPECT_TRUE(pRef->IsReference());
870 EXPECT_TRUE(pNum->IsNumber()); 870 EXPECT_TRUE(pNum->IsNumber());
871 EXPECT_NE(pObj, pRef); 871 EXPECT_NE(pObj, pRef);
872 EXPECT_EQ(pObj, pNum); 872 EXPECT_EQ(pObj, pNum);
873 EXPECT_EQ(42, dict->GetIntegerFor("clams")); 873 EXPECT_EQ(42, dict->GetIntegerFor("clams"));
874 } 874 }
OLDNEW
« no previous file with comments | « core/fpdfapi/parser/cpdf_document_unittest.cpp ('k') | core/fpdfapi/parser/cpdf_parser.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698