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

Side by Side Diff: core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp

Issue 1585533002: Fix infinite loops caused by calling circular indirect objects (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 11 months 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/include/fpdfapi/fpdf_objects.h ('k') | fpdfsdk/src/fpdfview_embeddertest.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 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "core/include/fpdfapi/fpdf_objects.h" 7 #include "core/include/fpdfapi/fpdf_objects.h"
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "core/include/fpdfapi/fpdf_parser.h" 11 #include "core/include/fpdfapi/fpdf_parser.h"
12 #include "core/include/fxcrt/fx_string.h" 12 #include "core/include/fxcrt/fx_string.h"
13 #include "third_party/base/stl_util.h" 13 #include "third_party/base/stl_util.h"
14 14
15 namespace { 15 namespace {
16 16
17 const FX_DWORD kBlockSize = 1024; 17 const FX_DWORD kBlockSize = 1024;
18 18
19 } // namespace 19 } // namespace
20 20
21 // static
22 int CPDF_Object::s_nCurRefDepth = 0;
23
24 void CPDF_Object::Release() { 21 void CPDF_Object::Release() {
25 if (m_ObjNum) { 22 if (m_ObjNum) {
26 return; 23 return;
27 } 24 }
28 Destroy(); 25 Destroy();
29 } 26 }
30 void CPDF_Object::Destroy() { 27 void CPDF_Object::Destroy() {
31 switch (m_Type) { 28 switch (m_Type) {
32 case PDFOBJ_STRING: 29 case PDFOBJ_STRING:
33 delete AsString(); 30 delete AsString();
34 break; 31 break;
35 case PDFOBJ_NAME: 32 case PDFOBJ_NAME:
36 delete AsName(); 33 delete AsName();
37 break; 34 break;
38 case PDFOBJ_ARRAY: 35 case PDFOBJ_ARRAY:
39 delete AsArray(); 36 delete AsArray();
40 break; 37 break;
41 case PDFOBJ_DICTIONARY: 38 case PDFOBJ_DICTIONARY:
42 delete AsDictionary(); 39 delete AsDictionary();
43 break; 40 break;
44 case PDFOBJ_STREAM: 41 case PDFOBJ_STREAM:
45 delete AsStream(); 42 delete AsStream();
46 break; 43 break;
47 default: 44 default:
48 delete this; 45 delete this;
49 } 46 }
50 } 47 }
48
49 const CPDF_Object* const CPDF_Object::GetBasicObject() const {
50 if (m_Type == PDFOBJ_REFERENCE) {
51 const CPDF_Reference* pRef = AsReference();
52 if (!pRef->m_pObjList)
53 return nullptr;
54
55 return pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr);
56 } else
Lei Zhang 2016/01/13 02:33:16 no else, or you can write the function as: if (m_
Wei Li 2016/01/13 06:18:43 Done.
57 return this;
58 }
59
51 CFX_ByteString CPDF_Object::GetString() const { 60 CFX_ByteString CPDF_Object::GetString() const {
52 switch (m_Type) { 61 const CPDF_Object* obj = GetBasicObject();
53 case PDFOBJ_BOOLEAN: 62 if (obj) {
54 return AsBoolean()->m_bValue ? "true" : "false"; 63 switch (obj->GetType()) {
55 case PDFOBJ_NUMBER: 64 case PDFOBJ_BOOLEAN:
56 return AsNumber()->GetString(); 65 return obj->AsBoolean()->GetString();
57 case PDFOBJ_STRING: 66 case PDFOBJ_NUMBER:
58 return AsString()->m_String; 67 return obj->AsNumber()->GetString();
59 case PDFOBJ_NAME: 68 case PDFOBJ_STRING:
60 return AsName()->m_Name; 69 return obj->AsString()->GetString();
61 case PDFOBJ_REFERENCE: { 70 case PDFOBJ_NAME:
62 const CPDF_Reference* pRef = AsReference(); 71 return obj->AsName()->GetString();
63 if (!pRef->m_pObjList)
64 break;
65
66 CPDF_Object* pObj =
67 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr);
68 return pObj ? pObj->GetString() : CFX_ByteString();
69 } 72 }
70 } 73 }
71 return CFX_ByteString(); 74 return CFX_ByteString();
72 } 75 }
76
73 CFX_ByteStringC CPDF_Object::GetConstString() const { 77 CFX_ByteStringC CPDF_Object::GetConstString() const {
74 switch (m_Type) { 78 const CPDF_Object* obj = GetBasicObject();
75 case PDFOBJ_STRING: { 79 if (obj) {
76 CFX_ByteString str = AsString()->m_String; 80 switch (obj->GetType()) {
77 return CFX_ByteStringC((const uint8_t*)str, str.GetLength()); 81 case PDFOBJ_STRING: {
78 } 82 CFX_ByteString str = obj->AsString()->GetString();
79 case PDFOBJ_NAME: { 83 return CFX_ByteStringC((const uint8_t*)str, str.GetLength());
Lei Zhang 2016/01/13 02:33:16 Can we switch to the "CFX_ByteStringC(const CFX_By
Wei Li 2016/01/13 06:18:43 Done.
80 CFX_ByteString name = AsName()->m_Name; 84 }
81 return CFX_ByteStringC((const uint8_t*)name, name.GetLength()); 85 case PDFOBJ_NAME: {
82 } 86 CFX_ByteString name = obj->AsName()->GetString();
83 case PDFOBJ_REFERENCE: { 87 return CFX_ByteStringC((const uint8_t*)name, name.GetLength());
84 const CPDF_Reference* pRef = AsReference(); 88 }
85 if (!pRef->m_pObjList)
86 break;
87
88 CPDF_Object* pObj =
89 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr);
90 return pObj ? pObj->GetConstString() : CFX_ByteStringC();
91 } 89 }
92 } 90 }
93 return CFX_ByteStringC(); 91 return CFX_ByteStringC();
94 } 92 }
95 93
96 FX_FLOAT CPDF_Object::GetNumber() const { 94 FX_FLOAT CPDF_Object::GetNumber() const {
97 switch (m_Type) { 95 const CPDF_Object* obj = GetBasicObject();
98 case PDFOBJ_NUMBER: 96 if (obj && obj->GetType() == PDFOBJ_NUMBER)
99 return AsNumber()->GetNumber(); 97 return AsNumber()->GetNumber();
100 case PDFOBJ_REFERENCE: {
101 const CPDF_Reference* pRef = AsReference();
102 if (!pRef->m_pObjList)
103 break;
104
105 CPDF_Object* pObj =
106 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr);
107 return pObj ? pObj->GetNumber() : 0;
108 }
109 }
110 return 0; 98 return 0;
111 } 99 }
112 100
113 FX_FLOAT CPDF_Object::GetNumber16() const { 101 FX_FLOAT CPDF_Object::GetNumber16() const {
114 return GetNumber(); 102 return GetNumber();
115 } 103 }
116 104
117 int CPDF_Object::GetInteger() const { 105 int CPDF_Object::GetInteger() const {
118 CFX_AutoRestorer<int> restorer(&s_nCurRefDepth); 106 const CPDF_Object* obj = GetBasicObject();
119 if (++s_nCurRefDepth > kObjectRefMaxDepth) 107 if (obj) {
120 return 0; 108 switch (obj->GetType()) {
121 109 case PDFOBJ_BOOLEAN:
122 switch (m_Type) { 110 return obj->AsBoolean()->GetValue();
123 case PDFOBJ_BOOLEAN: 111 case PDFOBJ_NUMBER:
124 return AsBoolean()->m_bValue; 112 return obj->AsNumber()->GetInteger();
125 case PDFOBJ_NUMBER:
126 return AsNumber()->GetInteger();
127 case PDFOBJ_REFERENCE: {
128 const CPDF_Reference* pRef = AsReference();
129 PARSE_CONTEXT context;
130 FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT));
131 if (!pRef->m_pObjList)
132 return 0;
133
134 CPDF_Object* pObj =
135 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), &context);
136 return pObj ? pObj->GetInteger() : 0;
137 } 113 }
138 } 114 }
139 return 0; 115 return 0;
140 } 116 }
141 117
142 CPDF_Dictionary* CPDF_Object::GetDict() const { 118 CPDF_Dictionary* CPDF_Object::GetDict() const {
143 switch (m_Type) { 119 const CPDF_Object* obj = GetBasicObject();
144 case PDFOBJ_DICTIONARY: 120 if (obj) {
145 // The method should be made non-const if we want to not be const. 121 switch (obj->GetType()) {
146 // See bug #234. 122 case PDFOBJ_DICTIONARY:
147 return const_cast<CPDF_Dictionary*>(AsDictionary()); 123 // The method should be made non-const if we want to not be const.
148 case PDFOBJ_STREAM: 124 // See bug #234.
149 return AsStream()->GetDict(); 125 return const_cast<CPDF_Dictionary*>(AsDictionary());
150 case PDFOBJ_REFERENCE: { 126 case PDFOBJ_STREAM:
151 const CPDF_Reference* pRef = AsReference(); 127 return AsStream()->GetDict();
152 CPDF_IndirectObjectHolder* pIndirect = pRef->GetObjList();
153 if (!pIndirect)
154 return nullptr;
155 CPDF_Object* pObj =
156 pIndirect->GetIndirectObject(pRef->GetRefObjNum(), nullptr);
157 if (!pObj || (pObj == this))
158 return nullptr;
159 return pObj->GetDict();
160 } 128 }
161 default:
162 return nullptr;
163 } 129 }
130 return nullptr;
164 } 131 }
165 132
166 CPDF_Array* CPDF_Object::GetArray() const { 133 CPDF_Array* CPDF_Object::GetArray() const {
167 // The method should be made non-const if we want to not be const. 134 // The method should be made non-const if we want to not be const.
168 // See bug #234. 135 // See bug #234.
169 return const_cast<CPDF_Array*>(AsArray()); 136 return const_cast<CPDF_Array*>(AsArray());
170 } 137 }
171 138
172 void CPDF_Object::SetString(const CFX_ByteString& str) { 139 void CPDF_Object::SetString(const CFX_ByteString& str) {
173 switch (m_Type) { 140 switch (m_Type) {
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 pObj->Destroy(); 1097 pObj->Destroy();
1131 return FALSE; 1098 return FALSE;
1132 } 1099 }
1133 it->second->Destroy(); 1100 it->second->Destroy();
1134 } 1101 }
1135 pObj->m_ObjNum = objnum; 1102 pObj->m_ObjNum = objnum;
1136 m_IndirectObjs[objnum] = pObj; 1103 m_IndirectObjs[objnum] = pObj;
1137 m_LastObjNum = std::max(m_LastObjNum, objnum); 1104 m_LastObjNum = std::max(m_LastObjNum, objnum);
1138 return TRUE; 1105 return TRUE;
1139 } 1106 }
OLDNEW
« no previous file with comments | « core/include/fpdfapi/fpdf_objects.h ('k') | fpdfsdk/src/fpdfview_embeddertest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698