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

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

Issue 1306793002: Fix infinite loop for objects that reference themselves. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: GetRefObjNum Created 5 years, 3 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 | « no previous file | no next file » | 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 "../../../include/fpdfapi/fpdf_parser.h" 7 #include "../../../include/fpdfapi/fpdf_parser.h"
8 #include "../../../include/fxcrt/fx_string.h" 8 #include "../../../include/fxcrt/fx_string.h"
9 9
10 // static 10 // static
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 case PDFOBJ_STRING: 46 case PDFOBJ_STRING:
47 return ((CPDF_String*)this)->m_String; 47 return ((CPDF_String*)this)->m_String;
48 case PDFOBJ_NAME: 48 case PDFOBJ_NAME:
49 return ((CPDF_Name*)this)->m_Name; 49 return ((CPDF_Name*)this)->m_Name;
50 case PDFOBJ_REFERENCE: { 50 case PDFOBJ_REFERENCE: {
51 CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; 51 CPDF_Reference* pRef = (CPDF_Reference*)(void*)this;
52 if (pRef->m_pObjList == NULL) { 52 if (pRef->m_pObjList == NULL) {
53 break; 53 break;
54 } 54 }
55 CPDF_Object* pObj = 55 CPDF_Object* pObj =
56 pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); 56 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum());
57 if (pObj == NULL) { 57 if (pObj == NULL) {
58 return CFX_ByteString(); 58 return CFX_ByteString();
59 } 59 }
60 return pObj->GetString(); 60 return pObj->GetString();
61 } 61 }
62 } 62 }
63 return CFX_ByteString(); 63 return CFX_ByteString();
64 } 64 }
65 CFX_ByteStringC CPDF_Object::GetConstString() const { 65 CFX_ByteStringC CPDF_Object::GetConstString() const {
66 switch (m_Type) { 66 switch (m_Type) {
67 case PDFOBJ_STRING: 67 case PDFOBJ_STRING:
68 return CFX_ByteStringC((const uint8_t*)((CPDF_String*)this)->m_String, 68 return CFX_ByteStringC((const uint8_t*)((CPDF_String*)this)->m_String,
69 ((CPDF_String*)this)->m_String.GetLength()); 69 ((CPDF_String*)this)->m_String.GetLength());
70 case PDFOBJ_NAME: 70 case PDFOBJ_NAME:
71 return CFX_ByteStringC((const uint8_t*)((CPDF_Name*)this)->m_Name, 71 return CFX_ByteStringC((const uint8_t*)((CPDF_Name*)this)->m_Name,
72 ((CPDF_Name*)this)->m_Name.GetLength()); 72 ((CPDF_Name*)this)->m_Name.GetLength());
73 case PDFOBJ_REFERENCE: { 73 case PDFOBJ_REFERENCE: {
74 CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; 74 CPDF_Reference* pRef = (CPDF_Reference*)(void*)this;
75 if (pRef->m_pObjList == NULL) { 75 if (pRef->m_pObjList == NULL) {
76 break; 76 break;
77 } 77 }
78 CPDF_Object* pObj = 78 CPDF_Object* pObj =
79 pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); 79 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum());
80 if (pObj == NULL) { 80 if (pObj == NULL) {
81 return CFX_ByteStringC(); 81 return CFX_ByteStringC();
82 } 82 }
83 return pObj->GetConstString(); 83 return pObj->GetConstString();
84 } 84 }
85 } 85 }
86 return CFX_ByteStringC(); 86 return CFX_ByteStringC();
87 } 87 }
88 FX_FLOAT CPDF_Object::GetNumber() const { 88 FX_FLOAT CPDF_Object::GetNumber() const {
89 switch (m_Type) { 89 switch (m_Type) {
90 case PDFOBJ_NUMBER: 90 case PDFOBJ_NUMBER:
91 return ((CPDF_Number*)this)->GetNumber(); 91 return ((CPDF_Number*)this)->GetNumber();
92 case PDFOBJ_REFERENCE: { 92 case PDFOBJ_REFERENCE: {
93 CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; 93 CPDF_Reference* pRef = (CPDF_Reference*)(void*)this;
94 if (pRef->m_pObjList == NULL) { 94 if (pRef->m_pObjList == NULL) {
95 break; 95 break;
96 } 96 }
97 CPDF_Object* pObj = 97 CPDF_Object* pObj =
98 pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); 98 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum());
99 if (pObj == NULL) { 99 if (pObj == NULL) {
100 return 0; 100 return 0;
101 } 101 }
102 return pObj->GetNumber(); 102 return pObj->GetNumber();
103 } 103 }
104 } 104 }
105 return 0; 105 return 0;
106 } 106 }
107 FX_FLOAT CPDF_Object::GetNumber16() const { 107 FX_FLOAT CPDF_Object::GetNumber16() const {
108 return GetNumber(); 108 return GetNumber();
109 } 109 }
110 int CPDF_Object::GetInteger() const { 110 int CPDF_Object::GetInteger() const {
111 CFX_AutoRestorer<int> restorer(&s_nCurRefDepth); 111 CFX_AutoRestorer<int> restorer(&s_nCurRefDepth);
112 if (++s_nCurRefDepth > OBJECT_REF_MAX_DEPTH) { 112 if (++s_nCurRefDepth > OBJECT_REF_MAX_DEPTH) {
113 return 0; 113 return 0;
114 } 114 }
115 switch (m_Type) { 115 switch (m_Type) {
116 case PDFOBJ_BOOLEAN: 116 case PDFOBJ_BOOLEAN:
117 return ((CPDF_Boolean*)this)->m_bValue; 117 return ((CPDF_Boolean*)this)->m_bValue;
118 case PDFOBJ_NUMBER: 118 case PDFOBJ_NUMBER:
119 return ((CPDF_Number*)this)->GetInteger(); 119 return ((CPDF_Number*)this)->GetInteger();
120 case PDFOBJ_REFERENCE: { 120 case PDFOBJ_REFERENCE: {
121 CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; 121 CPDF_Reference* pRef = (CPDF_Reference*)(void*)this;
122 PARSE_CONTEXT context; 122 PARSE_CONTEXT context;
123 FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT)); 123 FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT));
124 if (pRef->m_pObjList == NULL) { 124 if (pRef->m_pObjList == NULL) {
125 return 0; 125 return 0;
126 } 126 }
127 CPDF_Object* pObj = 127 CPDF_Object* pObj =
128 pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum, &context); 128 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), &context);
129 if (pObj == NULL) { 129 if (pObj == NULL) {
130 return 0; 130 return 0;
131 } 131 }
132 return pObj->GetInteger(); 132 return pObj->GetInteger();
133 } 133 }
134 } 134 }
135 return 0; 135 return 0;
136 } 136 }
137
137 CPDF_Dictionary* CPDF_Object::GetDict() const { 138 CPDF_Dictionary* CPDF_Object::GetDict() const {
138 switch (m_Type) { 139 switch (m_Type) {
139 case PDFOBJ_DICTIONARY: 140 case PDFOBJ_DICTIONARY:
140 return (CPDF_Dictionary*)this; 141 return (CPDF_Dictionary*)this;
141 case PDFOBJ_STREAM: 142 case PDFOBJ_STREAM:
142 return ((CPDF_Stream*)this)->GetDict(); 143 return ((CPDF_Stream*)this)->GetDict();
143 case PDFOBJ_REFERENCE: { 144 case PDFOBJ_REFERENCE: {
144 CPDF_Reference* pRef = (CPDF_Reference*)this; 145 CPDF_Reference* pRef = (CPDF_Reference*)this;
145 if (pRef->m_pObjList == NULL) { 146 CPDF_IndirectObjects* pIndirect = pRef->GetObjList();
146 break; 147 if (!pIndirect)
147 } 148 return nullptr;
148 CPDF_Object* pObj = 149 CPDF_Object* pObj = pIndirect->GetIndirectObject(pRef->GetRefObjNum());
149 pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); 150 if (!pObj || (pObj == this))
150 if (pObj == NULL) { 151 return nullptr;
151 return NULL;
152 }
153 return pObj->GetDict(); 152 return pObj->GetDict();
154 } 153 }
154 default:
155 return nullptr;
155 } 156 }
156 return NULL;
157 } 157 }
158
158 CPDF_Array* CPDF_Object::GetArray() const { 159 CPDF_Array* CPDF_Object::GetArray() const {
159 if (m_Type == PDFOBJ_ARRAY) 160 if (m_Type == PDFOBJ_ARRAY)
160 return (CPDF_Array*)this; 161 return (CPDF_Array*)this;
161 162
162 return NULL; 163 return NULL;
163 } 164 }
164 void CPDF_Object::SetString(const CFX_ByteString& str) { 165 void CPDF_Object::SetString(const CFX_ByteString& str) {
165 ASSERT(this != NULL); 166 ASSERT(this != NULL);
166 switch (m_Type) { 167 switch (m_Type) {
167 case PDFOBJ_BOOLEAN: 168 case PDFOBJ_BOOLEAN:
168 ((CPDF_Boolean*)this)->m_bValue = str == FX_BSTRC("true") ? 1 : 0; 169 ((CPDF_Boolean*)this)->m_bValue = str == FX_BSTRC("true") ? 1 : 0;
169 return; 170 return;
170 case PDFOBJ_NUMBER: 171 case PDFOBJ_NUMBER:
171 ((CPDF_Number*)this)->SetString(str); 172 ((CPDF_Number*)this)->SetString(str);
172 return; 173 return;
173 case PDFOBJ_STRING: 174 case PDFOBJ_STRING:
174 ((CPDF_String*)this)->m_String = str; 175 ((CPDF_String*)this)->m_String = str;
175 return; 176 return;
176 case PDFOBJ_NAME: 177 case PDFOBJ_NAME:
177 ((CPDF_Name*)this)->m_Name = str; 178 ((CPDF_Name*)this)->m_Name = str;
178 return; 179 return;
179 } 180 }
180 ASSERT(FALSE); 181 ASSERT(FALSE);
181 } 182 }
182 int CPDF_Object::GetDirectType() const { 183 int CPDF_Object::GetDirectType() const {
183 if (m_Type != PDFOBJ_REFERENCE) { 184 if (m_Type != PDFOBJ_REFERENCE) {
184 return m_Type; 185 return m_Type;
185 } 186 }
186 CPDF_Reference* pRef = (CPDF_Reference*)this; 187 CPDF_Reference* pRef = (CPDF_Reference*)this;
187 return pRef->m_pObjList->GetIndirectType(pRef->m_RefObjNum); 188 return pRef->m_pObjList->GetIndirectType(pRef->GetRefObjNum());
188 } 189 }
189 FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const { 190 FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const {
190 if (this == pOther) { 191 if (this == pOther) {
191 return TRUE; 192 return TRUE;
192 } 193 }
193 if (pOther == NULL) { 194 if (pOther == NULL) {
194 return FALSE; 195 return FALSE;
195 } 196 }
196 if (pOther->m_Type != m_Type) { 197 if (pOther->m_Type != m_Type) {
197 if (m_Type == PDFOBJ_REFERENCE && GetDirect()) { 198 if (m_Type == PDFOBJ_REFERENCE && GetDirect()) {
(...skipping 27 matching lines...) Expand all
225 return FALSE; 226 return FALSE;
226 } 227 }
227 CPDF_Object* CPDF_Object::GetDirect() const { 228 CPDF_Object* CPDF_Object::GetDirect() const {
228 if (m_Type != PDFOBJ_REFERENCE) { 229 if (m_Type != PDFOBJ_REFERENCE) {
229 return (CPDF_Object*)this; 230 return (CPDF_Object*)this;
230 } 231 }
231 CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; 232 CPDF_Reference* pRef = (CPDF_Reference*)(void*)this;
232 if (pRef->m_pObjList == NULL) { 233 if (pRef->m_pObjList == NULL) {
233 return NULL; 234 return NULL;
234 } 235 }
235 return pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); 236 return pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum());
236 } 237 }
237 CPDF_Object* CPDF_Object::Clone(FX_BOOL bDirect) const { 238 CPDF_Object* CPDF_Object::Clone(FX_BOOL bDirect) const {
238 CFX_MapPtrToPtr visited; 239 CFX_MapPtrToPtr visited;
239 return CloneInternal(bDirect, &visited); 240 return CloneInternal(bDirect, &visited);
240 } 241 }
241 CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, 242 CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect,
242 CFX_MapPtrToPtr* visited) const { 243 CFX_MapPtrToPtr* visited) const {
243 switch (m_Type) { 244 switch (m_Type) {
244 case PDFOBJ_BOOLEAN: 245 case PDFOBJ_BOOLEAN:
245 return new CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue); 246 return new CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 acc.LoadAllData(pThis, TRUE); 283 acc.LoadAllData(pThis, TRUE);
283 FX_DWORD streamSize = acc.GetSize(); 284 FX_DWORD streamSize = acc.GetSize();
284 CPDF_Dictionary* pDict = pThis->GetDict(); 285 CPDF_Dictionary* pDict = pThis->GetDict();
285 if (pDict) 286 if (pDict)
286 pDict = (CPDF_Dictionary*)((CPDF_Object*)pDict) 287 pDict = (CPDF_Dictionary*)((CPDF_Object*)pDict)
287 ->CloneInternal(bDirect, visited); 288 ->CloneInternal(bDirect, visited);
288 return new CPDF_Stream(acc.DetachData(), streamSize, pDict); 289 return new CPDF_Stream(acc.DetachData(), streamSize, pDict);
289 } 290 }
290 case PDFOBJ_REFERENCE: { 291 case PDFOBJ_REFERENCE: {
291 CPDF_Reference* pRef = (CPDF_Reference*)this; 292 CPDF_Reference* pRef = (CPDF_Reference*)this;
292 FX_DWORD obj_num = pRef->m_RefObjNum; 293 FX_DWORD obj_num = pRef->GetRefObjNum();
293 if (bDirect && !visited->GetValueAt((void*)(uintptr_t)obj_num)) { 294 if (bDirect && !visited->GetValueAt((void*)(uintptr_t)obj_num)) {
294 visited->SetAt((void*)(uintptr_t)obj_num, (void*)1); 295 visited->SetAt((void*)(uintptr_t)obj_num, (void*)1);
295 if (!pRef->GetDirect()) 296 if (!pRef->GetDirect())
296 return nullptr; 297 return nullptr;
297 298
298 return pRef->GetDirect()->CloneInternal(TRUE, visited); 299 return pRef->GetDirect()->CloneInternal(TRUE, visited);
299 } 300 }
300 return new CPDF_Reference(pRef->m_pObjList, obj_num); 301 return new CPDF_Reference(pRef->m_pObjList, obj_num);
301 } 302 }
302 } 303 }
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 } 1198 }
1198 pObj->m_ObjNum = objnum; 1199 pObj->m_ObjNum = objnum;
1199 m_IndirectObjs.SetAt((void*)(uintptr_t)objnum, pObj); 1200 m_IndirectObjs.SetAt((void*)(uintptr_t)objnum, pObj);
1200 if (m_LastObjNum < objnum) { 1201 if (m_LastObjNum < objnum) {
1201 m_LastObjNum = objnum; 1202 m_LastObjNum = objnum;
1202 } 1203 }
1203 } 1204 }
1204 FX_DWORD CPDF_IndirectObjects::GetLastObjNum() const { 1205 FX_DWORD CPDF_IndirectObjects::GetLastObjNum() const {
1205 return m_LastObjNum; 1206 return m_LastObjNum;
1206 } 1207 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698