OLD | NEW |
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/fpdf_parser/cpdf_boolean.h" | 5 #include "core/fpdfapi/fpdf_parser/cpdf_boolean.h" |
6 #include "core/fpdfapi/fpdf_parser/cpdf_null.h" | 6 #include "core/fpdfapi/fpdf_parser/cpdf_null.h" |
7 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 7 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
8 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" | 8 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
9 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" | 9 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" |
10 #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" | 10 #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 // String objects. | 59 // String objects. |
60 CPDF_String* str_reg_obj = new CPDF_String(L"A simple test"); | 60 CPDF_String* str_reg_obj = new CPDF_String(L"A simple test"); |
61 CPDF_String* str_spec_obj = new CPDF_String(L"\t\n"); | 61 CPDF_String* str_spec_obj = new CPDF_String(L"\t\n"); |
62 // Name object. | 62 // Name object. |
63 CPDF_Name* name_obj = new CPDF_Name("space"); | 63 CPDF_Name* name_obj = new CPDF_Name("space"); |
64 // Array object. | 64 // Array object. |
65 m_ArrayObj = new CPDF_Array; | 65 m_ArrayObj = new CPDF_Array; |
66 m_ArrayObj->InsertAt(0, new CPDF_Number(8902)); | 66 m_ArrayObj->InsertAt(0, new CPDF_Number(8902)); |
67 m_ArrayObj->InsertAt(1, new CPDF_Name("address")); | 67 m_ArrayObj->InsertAt(1, new CPDF_Name("address")); |
68 // Dictionary object. | 68 // Dictionary object. |
69 m_DictObj = new CPDF_Dictionary; | 69 m_DictObj = new CPDF_Dictionary(CFX_WeakPtr<CFX_ByteStringPool>()); |
70 m_DictObj->SetFor("bool", new CPDF_Boolean(false)); | 70 m_DictObj->SetFor("bool", new CPDF_Boolean(false)); |
71 m_DictObj->SetFor("num", new CPDF_Number(0.23f)); | 71 m_DictObj->SetFor("num", new CPDF_Number(0.23f)); |
72 // Stream object. | 72 // Stream object. |
73 const char content[] = "abcdefghijklmnopqrstuvwxyz"; | 73 const char content[] = "abcdefghijklmnopqrstuvwxyz"; |
74 size_t buf_len = FX_ArraySize(content); | 74 size_t buf_len = FX_ArraySize(content); |
75 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_len)); | 75 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_len)); |
76 memcpy(buf, content, buf_len); | 76 memcpy(buf, content, buf_len); |
77 m_StreamDictObj = new CPDF_Dictionary; | 77 m_StreamDictObj = new CPDF_Dictionary(CFX_WeakPtr<CFX_ByteStringPool>()); |
78 m_StreamDictObj->SetFor("key1", new CPDF_String(L" test dict")); | 78 m_StreamDictObj->SetFor("key1", new CPDF_String(L" test dict")); |
79 m_StreamDictObj->SetFor("key2", new CPDF_Number(-1)); | 79 m_StreamDictObj->SetFor("key2", new CPDF_Number(-1)); |
80 CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj); | 80 CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj); |
81 // Null Object. | 81 // Null Object. |
82 CPDF_Null* null_obj = new CPDF_Null; | 82 CPDF_Null* null_obj = new CPDF_Null; |
83 // All direct objects. | 83 // All direct objects. |
84 CPDF_Object* objs[] = {boolean_false_obj, boolean_true_obj, number_int_obj, | 84 CPDF_Object* objs[] = {boolean_false_obj, boolean_true_obj, number_int_obj, |
85 number_float_obj, str_reg_obj, str_spec_obj, | 85 number_float_obj, str_reg_obj, str_spec_obj, |
86 name_obj, m_ArrayObj, m_DictObj, | 86 name_obj, m_ArrayObj, m_DictObj, |
87 stream_obj, null_obj}; | 87 stream_obj, null_obj}; |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 vals[i], // Array value. | 546 vals[i], // Array value. |
547 nullptr, // Dictionary value. | 547 nullptr, // Dictionary value. |
548 nullptr); // Stream value. | 548 nullptr); // Stream value. |
549 } | 549 } |
550 } | 550 } |
551 { | 551 { |
552 // Dictionary array. | 552 // Dictionary array. |
553 CPDF_Dictionary* vals[3]; | 553 CPDF_Dictionary* vals[3]; |
554 ScopedArray arr(new CPDF_Array); | 554 ScopedArray arr(new CPDF_Array); |
555 for (size_t i = 0; i < 3; ++i) { | 555 for (size_t i = 0; i < 3; ++i) { |
556 vals[i] = new CPDF_Dictionary; | 556 vals[i] = new CPDF_Dictionary(CFX_WeakPtr<CFX_ByteStringPool>()); |
557 for (size_t j = 0; j < 3; ++j) { | 557 for (size_t j = 0; j < 3; ++j) { |
558 std::string key("key"); | 558 std::string key("key"); |
559 char buf[33]; | 559 char buf[33]; |
560 key.append(FXSYS_itoa(j, buf, 10)); | 560 key.append(FXSYS_itoa(j, buf, 10)); |
561 int value = j + 200; | 561 int value = j + 200; |
562 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); | 562 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); |
563 } | 563 } |
564 arr->InsertAt(i, vals[i]); | 564 arr->InsertAt(i, vals[i]); |
565 } | 565 } |
566 for (size_t i = 0; i < 3; ++i) { | 566 for (size_t i = 0; i < 3; ++i) { |
567 TestArrayAccessors(arr.get(), i, // Array and index. | 567 TestArrayAccessors(arr.get(), i, // Array and index. |
568 "", // String value. | 568 "", // String value. |
569 nullptr, // Const string value. | 569 nullptr, // Const string value. |
570 0, // Integer value. | 570 0, // Integer value. |
571 0, // Float value. | 571 0, // Float value. |
572 nullptr, // Array value. | 572 nullptr, // Array value. |
573 vals[i], // Dictionary value. | 573 vals[i], // Dictionary value. |
574 nullptr); // Stream value. | 574 nullptr); // Stream value. |
575 } | 575 } |
576 } | 576 } |
577 { | 577 { |
578 // Stream array. | 578 // Stream array. |
579 CPDF_Dictionary* vals[3]; | 579 CPDF_Dictionary* vals[3]; |
580 CPDF_Stream* stream_vals[3]; | 580 CPDF_Stream* stream_vals[3]; |
581 ScopedArray arr(new CPDF_Array); | 581 ScopedArray arr(new CPDF_Array); |
582 for (size_t i = 0; i < 3; ++i) { | 582 for (size_t i = 0; i < 3; ++i) { |
583 vals[i] = new CPDF_Dictionary; | 583 vals[i] = new CPDF_Dictionary(CFX_WeakPtr<CFX_ByteStringPool>()); |
584 for (size_t j = 0; j < 3; ++j) { | 584 for (size_t j = 0; j < 3; ++j) { |
585 std::string key("key"); | 585 std::string key("key"); |
586 char buf[33]; | 586 char buf[33]; |
587 key.append(FXSYS_itoa(j, buf, 10)); | 587 key.append(FXSYS_itoa(j, buf, 10)); |
588 int value = j + 200; | 588 int value = j + 200; |
589 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); | 589 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); |
590 } | 590 } |
591 uint8_t content[] = "content: this is a stream"; | 591 uint8_t content[] = "content: this is a stream"; |
592 size_t data_size = FX_ArraySize(content); | 592 size_t data_size = FX_ArraySize(content); |
593 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size)); | 593 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size)); |
(...skipping 24 matching lines...) Expand all Loading... |
618 arr->InsertAt(5, new CPDF_Number(0.05f)); | 618 arr->InsertAt(5, new CPDF_Number(0.05f)); |
619 arr->InsertAt(6, new CPDF_String("", false)); | 619 arr->InsertAt(6, new CPDF_String("", false)); |
620 arr->InsertAt(7, new CPDF_String("It is a test!", false)); | 620 arr->InsertAt(7, new CPDF_String("It is a test!", false)); |
621 arr->InsertAt(8, new CPDF_Name("NAME")); | 621 arr->InsertAt(8, new CPDF_Name("NAME")); |
622 arr->InsertAt(9, new CPDF_Name("test")); | 622 arr->InsertAt(9, new CPDF_Name("test")); |
623 arr->InsertAt(10, new CPDF_Null()); | 623 arr->InsertAt(10, new CPDF_Null()); |
624 CPDF_Array* arr_val = new CPDF_Array; | 624 CPDF_Array* arr_val = new CPDF_Array; |
625 arr_val->AddNumber(1); | 625 arr_val->AddNumber(1); |
626 arr_val->AddNumber(2); | 626 arr_val->AddNumber(2); |
627 arr->InsertAt(11, arr_val); | 627 arr->InsertAt(11, arr_val); |
628 CPDF_Dictionary* dict_val = new CPDF_Dictionary; | 628 CPDF_Dictionary* dict_val = |
| 629 new CPDF_Dictionary(CFX_WeakPtr<CFX_ByteStringPool>()); |
629 dict_val->SetFor("key1", new CPDF_String("Linda", false)); | 630 dict_val->SetFor("key1", new CPDF_String("Linda", false)); |
630 dict_val->SetFor("key2", new CPDF_String("Zoe", false)); | 631 dict_val->SetFor("key2", new CPDF_String("Zoe", false)); |
631 arr->InsertAt(12, dict_val); | 632 arr->InsertAt(12, dict_val); |
632 CPDF_Dictionary* stream_dict = new CPDF_Dictionary; | 633 CPDF_Dictionary* stream_dict = |
| 634 new CPDF_Dictionary(CFX_WeakPtr<CFX_ByteStringPool>()); |
633 stream_dict->SetFor("key1", new CPDF_String("John", false)); | 635 stream_dict->SetFor("key1", new CPDF_String("John", false)); |
634 stream_dict->SetFor("key2", new CPDF_String("King", false)); | 636 stream_dict->SetFor("key2", new CPDF_String("King", false)); |
635 uint8_t data[] = "A stream for test"; | 637 uint8_t data[] = "A stream for test"; |
636 // The data buffer will be owned by stream object, so it needs to be | 638 // The data buffer will be owned by stream object, so it needs to be |
637 // dynamically allocated. | 639 // dynamically allocated. |
638 size_t buf_size = sizeof(data); | 640 size_t buf_size = sizeof(data); |
639 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_size)); | 641 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_size)); |
640 memcpy(buf, data, buf_size); | 642 memcpy(buf, data, buf_size); |
641 CPDF_Stream* stream_val = new CPDF_Stream(buf, buf_size, stream_dict); | 643 CPDF_Stream* stream_val = new CPDF_Stream(buf, buf_size, stream_dict); |
642 arr->InsertAt(13, stream_val); | 644 arr->InsertAt(13, stream_val); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 ASSERT_TRUE(cloned_array_object->IsArray()); | 763 ASSERT_TRUE(cloned_array_object->IsArray()); |
762 | 764 |
763 ScopedArray cloned_array(cloned_array_object->AsArray()); | 765 ScopedArray cloned_array(cloned_array_object->AsArray()); |
764 ASSERT_EQ(1U, cloned_array->GetCount()); | 766 ASSERT_EQ(1U, cloned_array->GetCount()); |
765 CPDF_Object* cloned_obj = cloned_array->GetObjectAt(0); | 767 CPDF_Object* cloned_obj = cloned_array->GetObjectAt(0); |
766 EXPECT_FALSE(cloned_obj); | 768 EXPECT_FALSE(cloned_obj); |
767 } | 769 } |
768 | 770 |
769 TEST(PDFDictionaryTest, CloneDirectObject) { | 771 TEST(PDFDictionaryTest, CloneDirectObject) { |
770 CPDF_IndirectObjectHolder objects_holder; | 772 CPDF_IndirectObjectHolder objects_holder; |
771 ScopedDict dict(new CPDF_Dictionary); | 773 ScopedDict dict(new CPDF_Dictionary(CFX_WeakPtr<CFX_ByteStringPool>())); |
772 dict->SetReferenceFor("foo", &objects_holder, 1234); | 774 dict->SetReferenceFor("foo", &objects_holder, 1234); |
773 ASSERT_EQ(1U, dict->GetCount()); | 775 ASSERT_EQ(1U, dict->GetCount()); |
774 CPDF_Object* obj = dict->GetObjectFor("foo"); | 776 CPDF_Object* obj = dict->GetObjectFor("foo"); |
775 ASSERT_TRUE(obj); | 777 ASSERT_TRUE(obj); |
776 EXPECT_TRUE(obj->IsReference()); | 778 EXPECT_TRUE(obj->IsReference()); |
777 | 779 |
778 CPDF_Object* cloned_dict_object = dict->CloneDirectObject(); | 780 CPDF_Object* cloned_dict_object = dict->CloneDirectObject(); |
779 ASSERT_TRUE(cloned_dict_object); | 781 ASSERT_TRUE(cloned_dict_object); |
780 ASSERT_TRUE(cloned_dict_object->IsDictionary()); | 782 ASSERT_TRUE(cloned_dict_object->IsDictionary()); |
781 | 783 |
782 ScopedDict cloned_dict(cloned_dict_object->AsDictionary()); | 784 ScopedDict cloned_dict(cloned_dict_object->AsDictionary()); |
783 ASSERT_EQ(1U, cloned_dict->GetCount()); | 785 ASSERT_EQ(1U, cloned_dict->GetCount()); |
784 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo"); | 786 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo"); |
785 EXPECT_FALSE(cloned_obj); | 787 EXPECT_FALSE(cloned_obj); |
786 } | 788 } |
787 | 789 |
788 TEST(PDFObjectTest, CloneCheckLoop) { | 790 TEST(PDFObjectTest, CloneCheckLoop) { |
789 { | 791 { |
790 // Create an object with a reference loop. | 792 // Create an object with a reference loop. |
791 ScopedArray arr_obj(new CPDF_Array); | 793 ScopedArray arr_obj(new CPDF_Array); |
792 // Dictionary object. | 794 // Dictionary object. |
793 CPDF_Dictionary* dict_obj = new CPDF_Dictionary; | 795 CPDF_Dictionary* dict_obj = |
| 796 new CPDF_Dictionary(CFX_WeakPtr<CFX_ByteStringPool>()); |
794 dict_obj->SetFor("arr", arr_obj.get()); | 797 dict_obj->SetFor("arr", arr_obj.get()); |
795 arr_obj->InsertAt(0, dict_obj); | 798 arr_obj->InsertAt(0, dict_obj); |
796 | 799 |
797 // Clone this object to see whether stack overflow will be triggered. | 800 // Clone this object to see whether stack overflow will be triggered. |
798 ScopedArray cloned_array(arr_obj->Clone()->AsArray()); | 801 ScopedArray cloned_array(arr_obj->Clone()->AsArray()); |
799 // Cloned object should be the same as the original. | 802 // Cloned object should be the same as the original. |
800 ASSERT_TRUE(cloned_array); | 803 ASSERT_TRUE(cloned_array); |
801 EXPECT_EQ(1u, cloned_array->GetCount()); | 804 EXPECT_EQ(1u, cloned_array->GetCount()); |
802 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0); | 805 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0); |
803 ASSERT_TRUE(cloned_dict); | 806 ASSERT_TRUE(cloned_dict); |
804 ASSERT_TRUE(cloned_dict->IsDictionary()); | 807 ASSERT_TRUE(cloned_dict->IsDictionary()); |
805 // Recursively referenced object is not cloned. | 808 // Recursively referenced object is not cloned. |
806 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr")); | 809 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr")); |
807 } | 810 } |
808 { | 811 { |
809 CPDF_IndirectObjectHolder objects_holder; | 812 CPDF_IndirectObjectHolder objects_holder; |
810 // Create an object with a reference loop. | 813 // Create an object with a reference loop. |
811 CPDF_Dictionary* dict_obj = new CPDF_Dictionary; | 814 CPDF_Dictionary* dict_obj = |
| 815 new CPDF_Dictionary(CFX_WeakPtr<CFX_ByteStringPool>()); |
812 CPDF_Array* arr_obj = new CPDF_Array; | 816 CPDF_Array* arr_obj = new CPDF_Array; |
813 objects_holder.AddIndirectObject(dict_obj); | 817 objects_holder.AddIndirectObject(dict_obj); |
814 EXPECT_EQ(1u, dict_obj->GetObjNum()); | 818 EXPECT_EQ(1u, dict_obj->GetObjNum()); |
815 dict_obj->SetFor("arr", arr_obj); | 819 dict_obj->SetFor("arr", arr_obj); |
816 arr_obj->InsertAt( | 820 arr_obj->InsertAt( |
817 0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum())); | 821 0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum())); |
818 CPDF_Object* elem0 = arr_obj->GetObjectAt(0); | 822 CPDF_Object* elem0 = arr_obj->GetObjectAt(0); |
819 ASSERT_TRUE(elem0); | 823 ASSERT_TRUE(elem0); |
820 ASSERT_TRUE(elem0->IsReference()); | 824 ASSERT_TRUE(elem0->IsReference()); |
821 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum()); | 825 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum()); |
822 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect()); | 826 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect()); |
823 | 827 |
824 // Clone this object to see whether stack overflow will be triggered. | 828 // Clone this object to see whether stack overflow will be triggered. |
825 ScopedDict cloned_dict(ToDictionary(dict_obj->CloneDirectObject())); | 829 ScopedDict cloned_dict(ToDictionary(dict_obj->CloneDirectObject())); |
826 // Cloned object should be the same as the original. | 830 // Cloned object should be the same as the original. |
827 ASSERT_TRUE(cloned_dict); | 831 ASSERT_TRUE(cloned_dict); |
828 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr"); | 832 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr"); |
829 ASSERT_TRUE(cloned_arr); | 833 ASSERT_TRUE(cloned_arr); |
830 ASSERT_TRUE(cloned_arr->IsArray()); | 834 ASSERT_TRUE(cloned_arr->IsArray()); |
831 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount()); | 835 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount()); |
832 // Recursively referenced object is not cloned. | 836 // Recursively referenced object is not cloned. |
833 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0)); | 837 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0)); |
834 } | 838 } |
835 } | 839 } |
OLD | NEW |