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

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

Issue 1800523005: Move core/src/ up to core/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 9 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
OLDNEW
(Empty)
1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/include/fpdfapi/cpdf_array.h"
8 #include "core/include/fpdfapi/cpdf_dictionary.h"
9 #include "core/include/fpdfapi/cpdf_document.h"
10 #include "core/include/fpdfapi/cpdf_name.h"
11 #include "core/include/fpdfapi/cpdf_number.h"
12 #include "core/include/fpdfapi/cpdf_reference.h"
13 #include "core/include/fpdfapi/cpdf_stream.h"
14 #include "core/include/fxcrt/fx_ext.h"
15 #include "core/include/fxcrt/fx_safe_types.h"
16 #include "core/src/fpdfapi/fpdf_parser/cpdf_data_avail.h"
17 #include "core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.h"
18 #include "third_party/base/stl_util.h"
19
20 IPDF_DataAvail::IPDF_DataAvail(IPDF_DataAvail::FileAvail* pFileAvail,
21 IFX_FileRead* pFileRead)
22 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {}
23
24 IPDF_DataAvail::~IPDF_DataAvail() {}
25
26 IPDF_DataAvail::FileAvail::~FileAvail() {}
27
28 IPDF_DataAvail::DownloadHints::~DownloadHints() {}
29
30 // static
31 IPDF_DataAvail* IPDF_DataAvail::Create(IPDF_DataAvail::FileAvail* pFileAvail,
32 IFX_FileRead* pFileRead) {
33 return new CPDF_DataAvail(pFileAvail, pFileRead, TRUE);
34 }
35
36 // static
37 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0;
38
39 CPDF_DataAvail::CPDF_DataAvail(IPDF_DataAvail::FileAvail* pFileAvail,
40 IFX_FileRead* pFileRead,
41 FX_BOOL bSupportHintTable)
42 : IPDF_DataAvail(pFileAvail, pFileRead) {
43 m_Pos = 0;
44 m_dwFileLen = 0;
45 if (m_pFileRead) {
46 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
47 }
48 m_dwCurrentOffset = 0;
49 m_dwXRefOffset = 0;
50 m_bufferOffset = 0;
51 m_dwFirstPageNo = 0;
52 m_bufferSize = 0;
53 m_PagesObjNum = 0;
54 m_dwCurrentXRefSteam = 0;
55 m_dwAcroFormObjNum = 0;
56 m_dwInfoObjNum = 0;
57 m_pDocument = 0;
58 m_dwEncryptObjNum = 0;
59 m_dwPrevXRefOffset = 0;
60 m_dwLastXRefOffset = 0;
61 m_bDocAvail = FALSE;
62 m_bMainXRefLoadTried = FALSE;
63 m_bDocAvail = FALSE;
64 m_bLinearized = FALSE;
65 m_bPagesLoad = FALSE;
66 m_bPagesTreeLoad = FALSE;
67 m_bMainXRefLoadedOK = FALSE;
68 m_bAnnotsLoad = FALSE;
69 m_bHaveAcroForm = FALSE;
70 m_bAcroFormLoad = FALSE;
71 m_bPageLoadedOK = FALSE;
72 m_bNeedDownLoadResource = FALSE;
73 m_bLinearizedFormParamLoad = FALSE;
74 m_pLinearized = NULL;
75 m_pRoot = NULL;
76 m_pTrailer = NULL;
77 m_pCurrentParser = NULL;
78 m_pAcroForm = NULL;
79 m_pPageDict = NULL;
80 m_pPageResource = NULL;
81 m_docStatus = PDF_DATAAVAIL_HEADER;
82 m_parser.m_bOwnFileRead = false;
83 m_bTotalLoadPageTree = FALSE;
84 m_bCurPageDictLoadOK = FALSE;
85 m_bLinearedDataOK = FALSE;
86 m_bSupportHintTable = bSupportHintTable;
87 }
88 CPDF_DataAvail::~CPDF_DataAvail() {
89 if (m_pLinearized)
90 m_pLinearized->Release();
91
92 if (m_pRoot)
93 m_pRoot->Release();
94
95 if (m_pTrailer)
96 m_pTrailer->Release();
97
98 int iSize = m_arrayAcroforms.GetSize();
99 for (int i = 0; i < iSize; ++i)
100 m_arrayAcroforms.GetAt(i)->Release();
101 }
102
103 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) {
104 m_pDocument = pDoc;
105 }
106
107 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) {
108 CPDF_Parser* pParser = m_pDocument->GetParser();
109 if (!pParser || !pParser->IsValidObjectNumber(objnum))
110 return 0;
111
112 if (pParser->GetObjectType(objnum) == 2)
113 objnum = pParser->GetObjectPositionOrZero(objnum);
114
115 if (pParser->GetObjectType(objnum) != 1 &&
116 pParser->GetObjectType(objnum) != 255) {
117 return 0;
118 }
119
120 offset = pParser->GetObjectPositionOrZero(objnum);
121 if (offset == 0)
122 return 0;
123
124 auto it = pParser->m_SortedOffset.find(offset);
125 if (it == pParser->m_SortedOffset.end() ||
126 ++it == pParser->m_SortedOffset.end()) {
127 return 0;
128 }
129 return *it - offset;
130 }
131
132 FX_BOOL CPDF_DataAvail::IsObjectsAvail(
133 CFX_ArrayTemplate<CPDF_Object*>& obj_array,
134 FX_BOOL bParsePage,
135 IPDF_DataAvail::DownloadHints* pHints,
136 CFX_ArrayTemplate<CPDF_Object*>& ret_array) {
137 if (!obj_array.GetSize())
138 return TRUE;
139
140 FX_DWORD count = 0;
141 CFX_ArrayTemplate<CPDF_Object*> new_obj_array;
142 int32_t i = 0;
143 for (i = 0; i < obj_array.GetSize(); i++) {
144 CPDF_Object* pObj = obj_array[i];
145 if (!pObj)
146 continue;
147
148 int32_t type = pObj->GetType();
149 switch (type) {
150 case CPDF_Object::ARRAY: {
151 CPDF_Array* pArray = pObj->GetArray();
152 for (FX_DWORD k = 0; k < pArray->GetCount(); ++k)
153 new_obj_array.Add(pArray->GetElement(k));
154 } break;
155 case CPDF_Object::STREAM:
156 pObj = pObj->GetDict();
157 case CPDF_Object::DICTIONARY: {
158 CPDF_Dictionary* pDict = pObj->GetDict();
159 if (pDict && pDict->GetStringBy("Type") == "Page" && !bParsePage)
160 continue;
161
162 for (const auto& it : *pDict) {
163 const CFX_ByteString& key = it.first;
164 CPDF_Object* value = it.second;
165 if (key != "Parent")
166 new_obj_array.Add(value);
167 }
168 } break;
169 case CPDF_Object::REFERENCE: {
170 CPDF_Reference* pRef = pObj->AsReference();
171 FX_DWORD dwNum = pRef->GetRefObjNum();
172
173 FX_FILESIZE offset;
174 FX_DWORD size = GetObjectSize(dwNum, offset);
175 if (size == 0 || offset < 0 || offset >= m_dwFileLen)
176 break;
177
178 if (!IsDataAvail(offset, size, pHints)) {
179 ret_array.Add(pObj);
180 count++;
181 } else if (!pdfium::ContainsKey(m_ObjectSet, dwNum)) {
182 m_ObjectSet.insert(dwNum);
183 CPDF_Object* pReferred =
184 m_pDocument->GetIndirectObject(pRef->GetRefObjNum());
185 if (pReferred)
186 new_obj_array.Add(pReferred);
187 }
188 } break;
189 }
190 }
191
192 if (count > 0) {
193 int32_t iSize = new_obj_array.GetSize();
194 for (i = 0; i < iSize; ++i) {
195 CPDF_Object* pObj = new_obj_array[i];
196 if (CPDF_Reference* pRef = pObj->AsReference()) {
197 FX_DWORD dwNum = pRef->GetRefObjNum();
198 if (!pdfium::ContainsKey(m_ObjectSet, dwNum))
199 ret_array.Add(pObj);
200 } else {
201 ret_array.Add(pObj);
202 }
203 }
204 return FALSE;
205 }
206
207 obj_array.RemoveAll();
208 obj_array.Append(new_obj_array);
209 return IsObjectsAvail(obj_array, FALSE, pHints, ret_array);
210 }
211
212 IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsDocAvail(
213 IPDF_DataAvail::DownloadHints* pHints) {
214 if (!m_dwFileLen && m_pFileRead) {
215 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
216 if (!m_dwFileLen)
217 return DataError;
218 }
219
220 while (!m_bDocAvail) {
221 if (!CheckDocStatus(pHints))
222 return DataNotAvailable;
223 }
224
225 return DataAvailable;
226 }
227
228 FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(
229 IPDF_DataAvail::DownloadHints* pHints) {
230 if (!m_objs_array.GetSize()) {
231 m_objs_array.RemoveAll();
232 m_ObjectSet.clear();
233 CFX_ArrayTemplate<CPDF_Object*> obj_array;
234 obj_array.Append(m_arrayAcroforms);
235 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
236 if (bRet)
237 m_objs_array.RemoveAll();
238 return bRet;
239 }
240
241 CFX_ArrayTemplate<CPDF_Object*> new_objs_array;
242 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
243 if (bRet) {
244 int32_t iSize = m_arrayAcroforms.GetSize();
245 for (int32_t i = 0; i < iSize; ++i) {
246 m_arrayAcroforms.GetAt(i)->Release();
247 }
248 m_arrayAcroforms.RemoveAll();
249 } else {
250 m_objs_array.RemoveAll();
251 m_objs_array.Append(new_objs_array);
252 }
253 return bRet;
254 }
255
256 FX_BOOL CPDF_DataAvail::CheckAcroForm(IPDF_DataAvail::DownloadHints* pHints) {
257 FX_BOOL bExist = FALSE;
258 m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist);
259 if (!bExist) {
260 m_docStatus = PDF_DATAAVAIL_PAGETREE;
261 return TRUE;
262 }
263
264 if (!m_pAcroForm) {
265 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
266 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
267 return TRUE;
268 }
269 return FALSE;
270 }
271
272 m_arrayAcroforms.Add(m_pAcroForm);
273 m_docStatus = PDF_DATAAVAIL_PAGETREE;
274 return TRUE;
275 }
276
277 FX_BOOL CPDF_DataAvail::CheckDocStatus(IPDF_DataAvail::DownloadHints* pHints) {
278 switch (m_docStatus) {
279 case PDF_DATAAVAIL_HEADER:
280 return CheckHeader(pHints);
281 case PDF_DATAAVAIL_FIRSTPAGE:
282 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE:
283 return CheckFirstPage(pHints);
284 case PDF_DATAAVAIL_HINTTABLE:
285 return CheckHintTables(pHints);
286 case PDF_DATAAVAIL_END:
287 return CheckEnd(pHints);
288 case PDF_DATAAVAIL_CROSSREF:
289 return CheckCrossRef(pHints);
290 case PDF_DATAAVAIL_CROSSREF_ITEM:
291 return CheckCrossRefItem(pHints);
292 case PDF_DATAAVAIL_CROSSREF_STREAM:
293 return CheckAllCrossRefStream(pHints);
294 case PDF_DATAAVAIL_TRAILER:
295 return CheckTrailer(pHints);
296 case PDF_DATAAVAIL_TRAILER_APPEND:
297 return CheckTrailerAppend(pHints);
298 case PDF_DATAAVAIL_LOADALLCROSSREF:
299 return LoadAllXref(pHints);
300 case PDF_DATAAVAIL_LOADALLFILE:
301 return LoadAllFile(pHints);
302 case PDF_DATAAVAIL_ROOT:
303 return CheckRoot(pHints);
304 case PDF_DATAAVAIL_INFO:
305 return CheckInfo(pHints);
306 case PDF_DATAAVAIL_ACROFORM:
307 return CheckAcroForm(pHints);
308 case PDF_DATAAVAIL_PAGETREE:
309 if (m_bTotalLoadPageTree)
310 return CheckPages(pHints);
311 return LoadDocPages(pHints);
312 case PDF_DATAAVAIL_PAGE:
313 if (m_bTotalLoadPageTree)
314 return CheckPage(pHints);
315 m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD;
316 return TRUE;
317 case PDF_DATAAVAIL_ERROR:
318 return LoadAllFile(pHints);
319 case PDF_DATAAVAIL_PAGE_LATERLOAD:
320 m_docStatus = PDF_DATAAVAIL_PAGE;
321 default:
322 m_bDocAvail = TRUE;
323 return TRUE;
324 }
325 }
326
327 FX_BOOL CPDF_DataAvail::CheckPageStatus(IPDF_DataAvail::DownloadHints* pHints) {
328 switch (m_docStatus) {
329 case PDF_DATAAVAIL_PAGETREE:
330 return CheckPages(pHints);
331 case PDF_DATAAVAIL_PAGE:
332 return CheckPage(pHints);
333 case PDF_DATAAVAIL_ERROR:
334 return LoadAllFile(pHints);
335 default:
336 m_bPagesTreeLoad = TRUE;
337 m_bPagesLoad = TRUE;
338 return TRUE;
339 }
340 }
341
342 FX_BOOL CPDF_DataAvail::LoadAllFile(IPDF_DataAvail::DownloadHints* pHints) {
343 if (m_pFileAvail->IsDataAvail(0, (FX_DWORD)m_dwFileLen)) {
344 m_docStatus = PDF_DATAAVAIL_DONE;
345 return TRUE;
346 }
347
348 pHints->AddSegment(0, (FX_DWORD)m_dwFileLen);
349 return FALSE;
350 }
351
352 FX_BOOL CPDF_DataAvail::LoadAllXref(IPDF_DataAvail::DownloadHints* pHints) {
353 m_parser.m_pSyntax->InitParser(m_pFileRead, (FX_DWORD)m_dwHeaderOffset);
354 m_parser.m_bOwnFileRead = false;
355 if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) &&
356 !m_parser.LoadAllCrossRefV5(m_dwLastXRefOffset)) {
357 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
358 return FALSE;
359 }
360
361 m_dwRootObjNum = m_parser.GetRootObjNum();
362 m_dwInfoObjNum = m_parser.GetInfoObjNum();
363 m_pCurrentParser = &m_parser;
364 m_docStatus = PDF_DATAAVAIL_ROOT;
365 return TRUE;
366 }
367
368 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum,
369 IPDF_DataAvail::DownloadHints* pHints,
370 FX_BOOL* pExistInFile) {
371 CPDF_Object* pRet = nullptr;
372 FX_DWORD size = 0;
373 FX_FILESIZE offset = 0;
374 CPDF_Parser* pParser = nullptr;
375
376 if (pExistInFile)
377 *pExistInFile = TRUE;
378
379 if (m_pDocument) {
380 size = GetObjectSize(objnum, offset);
381 pParser = m_pDocument->GetParser();
382 } else {
383 size = (FX_DWORD)m_parser.GetObjectSize(objnum);
384 offset = m_parser.GetObjectOffset(objnum);
385 pParser = &m_parser;
386 }
387
388 if (!IsDataAvail(offset, size, pHints))
389 return nullptr;
390
391 if (pParser)
392 pRet = pParser->ParseIndirectObject(nullptr, objnum);
393
394 if (!pRet && pExistInFile)
395 *pExistInFile = FALSE;
396
397 return pRet;
398 }
399
400 FX_BOOL CPDF_DataAvail::CheckInfo(IPDF_DataAvail::DownloadHints* pHints) {
401 FX_BOOL bExist = FALSE;
402 CPDF_Object* pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist);
403 if (!bExist) {
404 m_docStatus =
405 (m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE);
406 return TRUE;
407 }
408
409 if (!pInfo) {
410 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
411 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
412 return TRUE;
413 }
414
415 if (m_Pos == m_dwFileLen)
416 m_docStatus = PDF_DATAAVAIL_ERROR;
417 return FALSE;
418 }
419
420 if (pInfo)
421 pInfo->Release();
422
423 m_docStatus =
424 (m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE);
425
426 return TRUE;
427 }
428
429 FX_BOOL CPDF_DataAvail::CheckRoot(IPDF_DataAvail::DownloadHints* pHints) {
430 FX_BOOL bExist = FALSE;
431 m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist);
432 if (!bExist) {
433 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
434 return TRUE;
435 }
436
437 if (!m_pRoot) {
438 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
439 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
440 return TRUE;
441 }
442 return FALSE;
443 }
444
445 CPDF_Dictionary* pDict = m_pRoot->GetDict();
446 if (!pDict) {
447 m_docStatus = PDF_DATAAVAIL_ERROR;
448 return FALSE;
449 }
450
451 CPDF_Reference* pRef = ToReference(pDict->GetElement("Pages"));
452 if (!pRef) {
453 m_docStatus = PDF_DATAAVAIL_ERROR;
454 return FALSE;
455 }
456
457 m_PagesObjNum = pRef->GetRefObjNum();
458 CPDF_Reference* pAcroFormRef =
459 ToReference(m_pRoot->GetDict()->GetElement("AcroForm"));
460 if (pAcroFormRef) {
461 m_bHaveAcroForm = TRUE;
462 m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum();
463 }
464
465 if (m_dwInfoObjNum) {
466 m_docStatus = PDF_DATAAVAIL_INFO;
467 } else {
468 m_docStatus =
469 m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE;
470 }
471 return TRUE;
472 }
473
474 FX_BOOL CPDF_DataAvail::PreparePageItem() {
475 CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
476 CPDF_Reference* pRef =
477 ToReference(pRoot ? pRoot->GetElement("Pages") : nullptr);
478 if (!pRef) {
479 m_docStatus = PDF_DATAAVAIL_ERROR;
480 return FALSE;
481 }
482
483 m_PagesObjNum = pRef->GetRefObjNum();
484 m_pCurrentParser = m_pDocument->GetParser();
485 m_docStatus = PDF_DATAAVAIL_PAGETREE;
486 return TRUE;
487 }
488
489 bool CPDF_DataAvail::IsFirstCheck(int iPage) {
490 return m_pageMapCheckState.insert(iPage).second;
491 }
492
493 void CPDF_DataAvail::ResetFirstCheck(int iPage) {
494 m_pageMapCheckState.erase(iPage);
495 }
496
497 FX_BOOL CPDF_DataAvail::CheckPage(IPDF_DataAvail::DownloadHints* pHints) {
498 FX_DWORD iPageObjs = m_PageObjList.GetSize();
499 CFX_DWordArray UnavailObjList;
500 for (FX_DWORD i = 0; i < iPageObjs; ++i) {
501 FX_DWORD dwPageObjNum = m_PageObjList.GetAt(i);
502 FX_BOOL bExist = FALSE;
503 CPDF_Object* pObj = GetObject(dwPageObjNum, pHints, &bExist);
504 if (!pObj) {
505 if (bExist)
506 UnavailObjList.Add(dwPageObjNum);
507 continue;
508 }
509
510 if (pObj->IsArray()) {
511 CPDF_Array* pArray = pObj->GetArray();
512 if (pArray) {
513 int32_t iSize = pArray->GetCount();
514 for (int32_t j = 0; j < iSize; ++j) {
515 if (CPDF_Reference* pRef = ToReference(pArray->GetElement(j)))
516 UnavailObjList.Add(pRef->GetRefObjNum());
517 }
518 }
519 }
520
521 if (!pObj->IsDictionary()) {
522 pObj->Release();
523 continue;
524 }
525
526 CFX_ByteString type = pObj->GetDict()->GetStringBy("Type");
527 if (type == "Pages") {
528 m_PagesArray.Add(pObj);
529 continue;
530 }
531 pObj->Release();
532 }
533
534 m_PageObjList.RemoveAll();
535 if (UnavailObjList.GetSize()) {
536 m_PageObjList.Append(UnavailObjList);
537 return FALSE;
538 }
539
540 FX_DWORD iPages = m_PagesArray.GetSize();
541 for (FX_DWORD i = 0; i < iPages; i++) {
542 CPDF_Object* pPages = m_PagesArray.GetAt(i);
543 if (!pPages)
544 continue;
545
546 if (!GetPageKids(m_pCurrentParser, pPages)) {
547 pPages->Release();
548 while (++i < iPages) {
549 pPages = m_PagesArray.GetAt(i);
550 pPages->Release();
551 }
552 m_PagesArray.RemoveAll();
553
554 m_docStatus = PDF_DATAAVAIL_ERROR;
555 return FALSE;
556 }
557 pPages->Release();
558 }
559
560 m_PagesArray.RemoveAll();
561 if (!m_PageObjList.GetSize())
562 m_docStatus = PDF_DATAAVAIL_DONE;
563 return TRUE;
564 }
565
566 FX_BOOL CPDF_DataAvail::GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages) {
567 if (!pParser) {
568 m_docStatus = PDF_DATAAVAIL_ERROR;
569 return FALSE;
570 }
571
572 CPDF_Dictionary* pDict = pPages->GetDict();
573 CPDF_Object* pKids = pDict ? pDict->GetElement("Kids") : NULL;
574 if (!pKids)
575 return TRUE;
576
577 switch (pKids->GetType()) {
578 case CPDF_Object::REFERENCE:
579 m_PageObjList.Add(pKids->AsReference()->GetRefObjNum());
580 break;
581 case CPDF_Object::ARRAY: {
582 CPDF_Array* pKidsArray = pKids->AsArray();
583 for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) {
584 if (CPDF_Reference* pRef = ToReference(pKidsArray->GetElement(i)))
585 m_PageObjList.Add(pRef->GetRefObjNum());
586 }
587 } break;
588 default:
589 m_docStatus = PDF_DATAAVAIL_ERROR;
590 return FALSE;
591 }
592 return TRUE;
593 }
594
595 FX_BOOL CPDF_DataAvail::CheckPages(IPDF_DataAvail::DownloadHints* pHints) {
596 FX_BOOL bExist = FALSE;
597 CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist);
598 if (!bExist) {
599 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
600 return TRUE;
601 }
602
603 if (!pPages) {
604 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
605 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
606 return TRUE;
607 }
608 return FALSE;
609 }
610
611 if (!GetPageKids(m_pCurrentParser, pPages)) {
612 pPages->Release();
613 m_docStatus = PDF_DATAAVAIL_ERROR;
614 return FALSE;
615 }
616
617 pPages->Release();
618 m_docStatus = PDF_DATAAVAIL_PAGE;
619 return TRUE;
620 }
621
622 FX_BOOL CPDF_DataAvail::CheckHeader(IPDF_DataAvail::DownloadHints* pHints) {
623 FX_DWORD req_size = 1024;
624 if ((FX_FILESIZE)req_size > m_dwFileLen)
625 req_size = (FX_DWORD)m_dwFileLen;
626
627 if (m_pFileAvail->IsDataAvail(0, req_size)) {
628 uint8_t buffer[1024];
629 m_pFileRead->ReadBlock(buffer, 0, req_size);
630
631 if (IsLinearizedFile(buffer, req_size)) {
632 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE;
633 } else {
634 if (m_docStatus == PDF_DATAAVAIL_ERROR)
635 return FALSE;
636 m_docStatus = PDF_DATAAVAIL_END;
637 }
638 return TRUE;
639 }
640
641 pHints->AddSegment(0, req_size);
642 return FALSE;
643 }
644
645 FX_BOOL CPDF_DataAvail::CheckFirstPage(IPDF_DataAvail::DownloadHints* pHints) {
646 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
647 CPDF_Object* pEndOffSet = pDict ? pDict->GetElement("E") : NULL;
648 if (!pEndOffSet) {
649 m_docStatus = PDF_DATAAVAIL_ERROR;
650 return FALSE;
651 }
652
653 CPDF_Object* pXRefOffset = pDict ? pDict->GetElement("T") : NULL;
654 if (!pXRefOffset) {
655 m_docStatus = PDF_DATAAVAIL_ERROR;
656 return FALSE;
657 }
658
659 CPDF_Object* pFileLen = pDict ? pDict->GetElement("L") : NULL;
660 if (!pFileLen) {
661 m_docStatus = PDF_DATAAVAIL_ERROR;
662 return FALSE;
663 }
664
665 FX_BOOL bNeedDownLoad = FALSE;
666 if (pEndOffSet->IsNumber()) {
667 FX_DWORD dwEnd = pEndOffSet->GetInteger();
668 dwEnd += 512;
669 if ((FX_FILESIZE)dwEnd > m_dwFileLen)
670 dwEnd = (FX_DWORD)m_dwFileLen;
671
672 int32_t iStartPos = (int32_t)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen);
673 int32_t iSize = dwEnd > 1024 ? dwEnd - 1024 : 0;
674 if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) {
675 pHints->AddSegment(iStartPos, iSize);
676 bNeedDownLoad = TRUE;
677 }
678 }
679
680 m_dwLastXRefOffset = 0;
681 FX_FILESIZE dwFileLen = 0;
682 if (pXRefOffset->IsNumber())
683 m_dwLastXRefOffset = pXRefOffset->GetInteger();
684
685 if (pFileLen->IsNumber())
686 dwFileLen = pFileLen->GetInteger();
687
688 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset,
689 (FX_DWORD)(dwFileLen - m_dwLastXRefOffset))) {
690 if (m_docStatus == PDF_DATAAVAIL_FIRSTPAGE) {
691 FX_DWORD dwSize = (FX_DWORD)(dwFileLen - m_dwLastXRefOffset);
692 FX_FILESIZE offset = m_dwLastXRefOffset;
693 if (dwSize < 512 && dwFileLen > 512) {
694 dwSize = 512;
695 offset = dwFileLen - 512;
696 }
697 pHints->AddSegment(offset, dwSize);
698 }
699 } else {
700 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
701 }
702
703 if (bNeedDownLoad || m_docStatus != PDF_DATAAVAIL_FIRSTPAGE_PREPARE) {
704 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
705 return FALSE;
706 }
707
708 m_docStatus =
709 m_bSupportHintTable ? PDF_DATAAVAIL_HINTTABLE : PDF_DATAAVAIL_DONE;
710 return TRUE;
711 }
712
713 FX_BOOL CPDF_DataAvail::IsDataAvail(FX_FILESIZE offset,
714 FX_DWORD size,
715 IPDF_DataAvail::DownloadHints* pHints) {
716 if (offset > m_dwFileLen)
717 return TRUE;
718
719 FX_SAFE_DWORD safeSize = pdfium::base::checked_cast<FX_DWORD>(offset);
720 safeSize += size;
721 safeSize += 512;
722 if (!safeSize.IsValid() || safeSize.ValueOrDie() > m_dwFileLen)
723 size = m_dwFileLen - offset;
724 else
725 size += 512;
726
727 if (!m_pFileAvail->IsDataAvail(offset, size)) {
728 pHints->AddSegment(offset, size);
729 return FALSE;
730 }
731 return TRUE;
732 }
733
734 FX_BOOL CPDF_DataAvail::CheckHintTables(IPDF_DataAvail::DownloadHints* pHints) {
735 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
736 if (!pDict) {
737 m_docStatus = PDF_DATAAVAIL_ERROR;
738 return FALSE;
739 }
740
741 if (!pDict->KeyExist("H") || !pDict->KeyExist("O") || !pDict->KeyExist("N")) {
742 m_docStatus = PDF_DATAAVAIL_ERROR;
743 return FALSE;
744 }
745
746 int nPageCount = pDict->GetElementValue("N")->GetInteger();
747 if (nPageCount <= 1) {
748 m_docStatus = PDF_DATAAVAIL_DONE;
749 return TRUE;
750 }
751
752 CPDF_Array* pHintStreamRange = pDict->GetArrayBy("H");
753 FX_FILESIZE szHSStart =
754 pHintStreamRange->GetElementValue(0)
755 ? pHintStreamRange->GetElementValue(0)->GetInteger()
756 : 0;
757 FX_FILESIZE szHSLength =
758 pHintStreamRange->GetElementValue(1)
759 ? pHintStreamRange->GetElementValue(1)->GetInteger()
760 : 0;
761 if (szHSStart < 0 || szHSLength <= 0) {
762 m_docStatus = PDF_DATAAVAIL_ERROR;
763 return FALSE;
764 }
765
766 if (!IsDataAvail(szHSStart, szHSLength, pHints))
767 return FALSE;
768
769 m_syntaxParser.InitParser(m_pFileRead, m_dwHeaderOffset);
770
771 std::unique_ptr<CPDF_HintTables> pHintTables(
772 new CPDF_HintTables(this, pDict));
773 std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pHintStream(
774 ParseIndirectObjectAt(szHSStart, 0));
775 CPDF_Stream* pStream = ToStream(pHintStream.get());
776 if (pStream && pHintTables->LoadHintStream(pStream))
777 m_pHintTables = std::move(pHintTables);
778
779 m_docStatus = PDF_DATAAVAIL_DONE;
780 return TRUE;
781 }
782
783 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(
784 FX_FILESIZE pos,
785 FX_DWORD objnum,
786 CPDF_IndirectObjectHolder* pObjList) {
787 FX_FILESIZE SavedPos = m_syntaxParser.SavePos();
788 m_syntaxParser.RestorePos(pos);
789
790 bool bIsNumber;
791 CFX_ByteString word = m_syntaxParser.GetNextWord(&bIsNumber);
792 if (!bIsNumber)
793 return nullptr;
794
795 FX_DWORD parser_objnum = FXSYS_atoui(word);
796 if (objnum && parser_objnum != objnum)
797 return nullptr;
798
799 word = m_syntaxParser.GetNextWord(&bIsNumber);
800 if (!bIsNumber)
801 return nullptr;
802
803 FX_DWORD gennum = FXSYS_atoui(word);
804 if (m_syntaxParser.GetKeyword() != "obj") {
805 m_syntaxParser.RestorePos(SavedPos);
806 return nullptr;
807 }
808
809 CPDF_Object* pObj =
810 m_syntaxParser.GetObject(pObjList, parser_objnum, gennum, true);
811 m_syntaxParser.RestorePos(SavedPos);
812 return pObj;
813 }
814
815 IPDF_DataAvail::DocLinearizationStatus CPDF_DataAvail::IsLinearizedPDF() {
816 FX_DWORD req_size = 1024;
817 if (!m_pFileAvail->IsDataAvail(0, req_size))
818 return LinearizationUnknown;
819
820 if (!m_pFileRead)
821 return NotLinearized;
822
823 FX_FILESIZE dwSize = m_pFileRead->GetSize();
824 if (dwSize < (FX_FILESIZE)req_size)
825 return LinearizationUnknown;
826
827 uint8_t buffer[1024];
828 m_pFileRead->ReadBlock(buffer, 0, req_size);
829 if (IsLinearizedFile(buffer, req_size))
830 return Linearized;
831
832 return NotLinearized;
833 }
834 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) {
835 ScopedFileStream file(FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE));
836
837 int32_t offset = GetHeaderOffset(file.get());
838 if (offset == -1) {
839 m_docStatus = PDF_DATAAVAIL_ERROR;
840 return FALSE;
841 }
842
843 m_dwHeaderOffset = offset;
844 m_syntaxParser.InitParser(file.get(), offset);
845 m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9);
846
847 bool bNumber;
848 CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(&bNumber);
849 if (!bNumber)
850 return FALSE;
851
852 FX_DWORD objnum = FXSYS_atoui(wordObjNum);
853 if (m_pLinearized) {
854 m_pLinearized->Release();
855 m_pLinearized = nullptr;
856 }
857
858 m_pLinearized =
859 ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum);
860 if (!m_pLinearized)
861 return FALSE;
862
863 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
864 if (pDict && pDict->GetElement("Linearized")) {
865 CPDF_Object* pLen = pDict->GetElement("L");
866 if (!pLen)
867 return FALSE;
868
869 if ((FX_FILESIZE)pLen->GetInteger() != m_pFileRead->GetSize())
870 return FALSE;
871
872 m_bLinearized = TRUE;
873
874 if (CPDF_Number* pNo = ToNumber(pDict->GetElement("P")))
875 m_dwFirstPageNo = pNo->GetInteger();
876
877 return TRUE;
878 }
879 return FALSE;
880 }
881
882 FX_BOOL CPDF_DataAvail::CheckEnd(IPDF_DataAvail::DownloadHints* pHints) {
883 FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0);
884 FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos);
885
886 if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) {
887 uint8_t buffer[1024];
888 m_pFileRead->ReadBlock(buffer, req_pos, dwSize);
889
890 ScopedFileStream file(FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE));
891 m_syntaxParser.InitParser(file.get(), 0);
892 m_syntaxParser.RestorePos(dwSize - 1);
893
894 if (m_syntaxParser.SearchWord("startxref", TRUE, FALSE, dwSize)) {
895 m_syntaxParser.GetNextWord(nullptr);
896
897 bool bNumber;
898 CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(&bNumber);
899 if (!bNumber) {
900 m_docStatus = PDF_DATAAVAIL_ERROR;
901 return FALSE;
902 }
903
904 m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str);
905 if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) {
906 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
907 return TRUE;
908 }
909
910 m_dwLastXRefOffset = m_dwXRefOffset;
911 SetStartOffset(m_dwXRefOffset);
912 m_docStatus = PDF_DATAAVAIL_CROSSREF;
913 return TRUE;
914 }
915
916 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
917 return TRUE;
918 }
919
920 pHints->AddSegment(req_pos, dwSize);
921 return FALSE;
922 }
923
924 int32_t CPDF_DataAvail::CheckCrossRefStream(
925 IPDF_DataAvail::DownloadHints* pHints,
926 FX_FILESIZE& xref_offset) {
927 xref_offset = 0;
928 FX_DWORD req_size =
929 (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
930
931 if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) {
932 int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam);
933 CFX_BinaryBuf buf(iSize);
934 uint8_t* pBuf = buf.GetBuffer();
935
936 m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize);
937
938 ScopedFileStream file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE));
939 m_parser.m_pSyntax->InitParser(file.get(), 0);
940
941 bool bNumber;
942 CFX_ByteString objnum = m_parser.m_pSyntax->GetNextWord(&bNumber);
943 if (!bNumber)
944 return -1;
945
946 FX_DWORD objNum = FXSYS_atoui(objnum);
947 CPDF_Object* pObj = m_parser.ParseIndirectObjectAt(nullptr, 0, objNum);
948 if (!pObj) {
949 m_Pos += m_parser.m_pSyntax->SavePos();
950 return 0;
951 }
952
953 CPDF_Dictionary* pDict = pObj->GetDict();
954 CPDF_Name* pName = ToName(pDict ? pDict->GetElement("Type") : nullptr);
955 if (pName) {
956 if (pName->GetString() == "XRef") {
957 m_Pos += m_parser.m_pSyntax->SavePos();
958 xref_offset = pObj->GetDict()->GetIntegerBy("Prev");
959 pObj->Release();
960 return 1;
961 }
962 }
963 pObj->Release();
964 return -1;
965 }
966 pHints->AddSegment(m_Pos, req_size);
967 return 0;
968 }
969
970 inline void CPDF_DataAvail::SetStartOffset(FX_FILESIZE dwOffset) {
971 m_Pos = dwOffset;
972 }
973
974 FX_BOOL CPDF_DataAvail::GetNextToken(CFX_ByteString& token) {
975 uint8_t ch;
976 if (!GetNextChar(ch))
977 return FALSE;
978
979 while (1) {
980 while (PDFCharIsWhitespace(ch)) {
981 if (!GetNextChar(ch))
982 return FALSE;
983 }
984
985 if (ch != '%')
986 break;
987
988 while (1) {
989 if (!GetNextChar(ch))
990 return FALSE;
991 if (PDFCharIsLineEnding(ch))
992 break;
993 }
994 }
995
996 uint8_t buffer[256];
997 FX_DWORD index = 0;
998 if (PDFCharIsDelimiter(ch)) {
999 buffer[index++] = ch;
1000 if (ch == '/') {
1001 while (1) {
1002 if (!GetNextChar(ch))
1003 return FALSE;
1004
1005 if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) {
1006 m_Pos--;
1007 CFX_ByteString ret(buffer, index);
1008 token = ret;
1009 return TRUE;
1010 }
1011
1012 if (index < sizeof(buffer))
1013 buffer[index++] = ch;
1014 }
1015 } else if (ch == '<') {
1016 if (!GetNextChar(ch))
1017 return FALSE;
1018
1019 if (ch == '<')
1020 buffer[index++] = ch;
1021 else
1022 m_Pos--;
1023 } else if (ch == '>') {
1024 if (!GetNextChar(ch))
1025 return FALSE;
1026
1027 if (ch == '>')
1028 buffer[index++] = ch;
1029 else
1030 m_Pos--;
1031 }
1032
1033 CFX_ByteString ret(buffer, index);
1034 token = ret;
1035 return TRUE;
1036 }
1037
1038 while (1) {
1039 if (index < sizeof(buffer))
1040 buffer[index++] = ch;
1041
1042 if (!GetNextChar(ch))
1043 return FALSE;
1044
1045 if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) {
1046 m_Pos--;
1047 break;
1048 }
1049 }
1050
1051 token = CFX_ByteString(buffer, index);
1052 return TRUE;
1053 }
1054
1055 FX_BOOL CPDF_DataAvail::GetNextChar(uint8_t& ch) {
1056 FX_FILESIZE pos = m_Pos;
1057 if (pos >= m_dwFileLen)
1058 return FALSE;
1059
1060 if (m_bufferOffset >= pos ||
1061 (FX_FILESIZE)(m_bufferOffset + m_bufferSize) <= pos) {
1062 FX_FILESIZE read_pos = pos;
1063 FX_DWORD read_size = 512;
1064 if ((FX_FILESIZE)read_size > m_dwFileLen)
1065 read_size = (FX_DWORD)m_dwFileLen;
1066
1067 if ((FX_FILESIZE)(read_pos + read_size) > m_dwFileLen)
1068 read_pos = m_dwFileLen - read_size;
1069
1070 if (!m_pFileRead->ReadBlock(m_bufferData, read_pos, read_size))
1071 return FALSE;
1072
1073 m_bufferOffset = read_pos;
1074 m_bufferSize = read_size;
1075 }
1076 ch = m_bufferData[pos - m_bufferOffset];
1077 m_Pos++;
1078 return TRUE;
1079 }
1080
1081 FX_BOOL CPDF_DataAvail::CheckCrossRefItem(
1082 IPDF_DataAvail::DownloadHints* pHints) {
1083 int32_t iSize = 0;
1084 CFX_ByteString token;
1085 while (1) {
1086 if (!GetNextToken(token)) {
1087 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
1088 pHints->AddSegment(m_Pos, iSize);
1089 return FALSE;
1090 }
1091
1092 if (token == "trailer") {
1093 m_dwTrailerOffset = m_Pos;
1094 m_docStatus = PDF_DATAAVAIL_TRAILER;
1095 return TRUE;
1096 }
1097 }
1098 }
1099
1100 FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(
1101 IPDF_DataAvail::DownloadHints* pHints) {
1102 FX_FILESIZE xref_offset = 0;
1103
1104 int32_t nRet = CheckCrossRefStream(pHints, xref_offset);
1105 if (nRet == 1) {
1106 if (!xref_offset) {
1107 m_docStatus = PDF_DATAAVAIL_LOADALLCROSSREF;
1108 } else {
1109 m_dwCurrentXRefSteam = xref_offset;
1110 m_Pos = xref_offset;
1111 }
1112 return TRUE;
1113 }
1114
1115 if (nRet == -1)
1116 m_docStatus = PDF_DATAAVAIL_ERROR;
1117 return FALSE;
1118 }
1119
1120 FX_BOOL CPDF_DataAvail::CheckCrossRef(IPDF_DataAvail::DownloadHints* pHints) {
1121 int32_t iSize = 0;
1122 CFX_ByteString token;
1123 if (!GetNextToken(token)) {
1124 iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
1125 pHints->AddSegment(m_Pos, iSize);
1126 return FALSE;
1127 }
1128
1129 if (token == "xref") {
1130 while (1) {
1131 if (!GetNextToken(token)) {
1132 iSize =
1133 (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
1134 pHints->AddSegment(m_Pos, iSize);
1135 m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM;
1136 return FALSE;
1137 }
1138
1139 if (token == "trailer") {
1140 m_dwTrailerOffset = m_Pos;
1141 m_docStatus = PDF_DATAAVAIL_TRAILER;
1142 return TRUE;
1143 }
1144 }
1145 } else {
1146 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
1147 return TRUE;
1148 }
1149 return FALSE;
1150 }
1151
1152 FX_BOOL CPDF_DataAvail::CheckTrailerAppend(
1153 IPDF_DataAvail::DownloadHints* pHints) {
1154 if (m_Pos < m_dwFileLen) {
1155 FX_FILESIZE dwAppendPos = m_Pos + m_syntaxParser.SavePos();
1156 int32_t iSize = (int32_t)(
1157 dwAppendPos + 512 > m_dwFileLen ? m_dwFileLen - dwAppendPos : 512);
1158
1159 if (!m_pFileAvail->IsDataAvail(dwAppendPos, iSize)) {
1160 pHints->AddSegment(dwAppendPos, iSize);
1161 return FALSE;
1162 }
1163 }
1164
1165 if (m_dwPrevXRefOffset) {
1166 SetStartOffset(m_dwPrevXRefOffset);
1167 m_docStatus = PDF_DATAAVAIL_CROSSREF;
1168 } else {
1169 m_docStatus = PDF_DATAAVAIL_LOADALLCROSSREF;
1170 }
1171 return TRUE;
1172 }
1173
1174 FX_BOOL CPDF_DataAvail::CheckTrailer(IPDF_DataAvail::DownloadHints* pHints) {
1175 int32_t iTrailerSize =
1176 (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
1177 if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) {
1178 int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset);
1179 CFX_BinaryBuf buf(iSize);
1180 uint8_t* pBuf = buf.GetBuffer();
1181 if (!pBuf) {
1182 m_docStatus = PDF_DATAAVAIL_ERROR;
1183 return FALSE;
1184 }
1185
1186 if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize))
1187 return FALSE;
1188
1189 ScopedFileStream file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE));
1190 m_syntaxParser.InitParser(file.get(), 0);
1191
1192 std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pTrailer(
1193 m_syntaxParser.GetObject(nullptr, 0, 0, true));
1194 if (!pTrailer) {
1195 m_Pos += m_syntaxParser.SavePos();
1196 pHints->AddSegment(m_Pos, iTrailerSize);
1197 return FALSE;
1198 }
1199
1200 if (!pTrailer->IsDictionary())
1201 return FALSE;
1202
1203 CPDF_Dictionary* pTrailerDict = pTrailer->GetDict();
1204 CPDF_Object* pEncrypt = pTrailerDict->GetElement("Encrypt");
1205 if (ToReference(pEncrypt)) {
1206 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
1207 return TRUE;
1208 }
1209
1210 FX_DWORD xrefpos = GetDirectInteger(pTrailerDict, "Prev");
1211 if (xrefpos) {
1212 m_dwPrevXRefOffset = GetDirectInteger(pTrailerDict, "XRefStm");
1213 if (m_dwPrevXRefOffset) {
1214 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
1215 } else {
1216 m_dwPrevXRefOffset = xrefpos;
1217 if (m_dwPrevXRefOffset >= m_dwFileLen) {
1218 m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
1219 } else {
1220 SetStartOffset(m_dwPrevXRefOffset);
1221 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
1222 }
1223 }
1224 return TRUE;
1225 }
1226 m_dwPrevXRefOffset = 0;
1227 m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
1228 return TRUE;
1229 }
1230 pHints->AddSegment(m_Pos, iTrailerSize);
1231 return FALSE;
1232 }
1233
1234 FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage,
1235 IPDF_DataAvail::DownloadHints* pHints) {
1236 while (TRUE) {
1237 switch (m_docStatus) {
1238 case PDF_DATAAVAIL_PAGETREE:
1239 if (!LoadDocPages(pHints))
1240 return FALSE;
1241 break;
1242 case PDF_DATAAVAIL_PAGE:
1243 if (!LoadDocPage(iPage, pHints))
1244 return FALSE;
1245 break;
1246 case PDF_DATAAVAIL_ERROR:
1247 return LoadAllFile(pHints);
1248 default:
1249 m_bPagesTreeLoad = TRUE;
1250 m_bPagesLoad = TRUE;
1251 m_bCurPageDictLoadOK = TRUE;
1252 m_docStatus = PDF_DATAAVAIL_PAGE;
1253 return TRUE;
1254 }
1255 }
1256 }
1257
1258 FX_BOOL CPDF_DataAvail::CheckArrayPageNode(
1259 FX_DWORD dwPageNo,
1260 CPDF_DataAvail::PageNode* pPageNode,
1261 IPDF_DataAvail::DownloadHints* pHints) {
1262 FX_BOOL bExist = FALSE;
1263 CPDF_Object* pPages = GetObject(dwPageNo, pHints, &bExist);
1264 if (!bExist) {
1265 m_docStatus = PDF_DATAAVAIL_ERROR;
1266 return FALSE;
1267 }
1268
1269 if (!pPages) {
1270 if (m_docStatus == PDF_DATAAVAIL_ERROR) {
1271 m_docStatus = PDF_DATAAVAIL_ERROR;
1272 return FALSE;
1273 }
1274 return FALSE;
1275 }
1276
1277 CPDF_Array* pArray = pPages->AsArray();
1278 if (!pArray) {
1279 pPages->Release();
1280 m_docStatus = PDF_DATAAVAIL_ERROR;
1281 return FALSE;
1282 }
1283
1284 pPageNode->m_type = PDF_PAGENODE_PAGES;
1285 for (FX_DWORD i = 0; i < pArray->GetCount(); ++i) {
1286 CPDF_Reference* pKid = ToReference(pArray->GetElement(i));
1287 if (!pKid)
1288 continue;
1289
1290 PageNode* pNode = new PageNode();
1291 pPageNode->m_childNode.Add(pNode);
1292 pNode->m_dwPageNo = pKid->GetRefObjNum();
1293 }
1294 pPages->Release();
1295 return TRUE;
1296 }
1297
1298 FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(
1299 FX_DWORD dwPageNo,
1300 CPDF_DataAvail::PageNode* pPageNode,
1301 IPDF_DataAvail::DownloadHints* pHints) {
1302 FX_BOOL bExist = FALSE;
1303 CPDF_Object* pPage = GetObject(dwPageNo, pHints, &bExist);
1304 if (!bExist) {
1305 m_docStatus = PDF_DATAAVAIL_ERROR;
1306 return FALSE;
1307 }
1308
1309 if (!pPage) {
1310 if (m_docStatus == PDF_DATAAVAIL_ERROR)
1311 m_docStatus = PDF_DATAAVAIL_ERROR;
1312 return FALSE;
1313 }
1314
1315 if (pPage->IsArray()) {
1316 pPageNode->m_dwPageNo = dwPageNo;
1317 pPageNode->m_type = PDF_PAGENODE_ARRAY;
1318 pPage->Release();
1319 return TRUE;
1320 }
1321
1322 if (!pPage->IsDictionary()) {
1323 pPage->Release();
1324 m_docStatus = PDF_DATAAVAIL_ERROR;
1325 return FALSE;
1326 }
1327
1328 pPageNode->m_dwPageNo = dwPageNo;
1329 CPDF_Dictionary* pDict = pPage->GetDict();
1330 CFX_ByteString type = pDict->GetStringBy("Type");
1331 if (type == "Pages") {
1332 pPageNode->m_type = PDF_PAGENODE_PAGES;
1333 CPDF_Object* pKids = pDict->GetElement("Kids");
1334 if (!pKids) {
1335 m_docStatus = PDF_DATAAVAIL_PAGE;
1336 return TRUE;
1337 }
1338
1339 switch (pKids->GetType()) {
1340 case CPDF_Object::REFERENCE: {
1341 CPDF_Reference* pKid = pKids->AsReference();
1342 PageNode* pNode = new PageNode();
1343 pPageNode->m_childNode.Add(pNode);
1344 pNode->m_dwPageNo = pKid->GetRefObjNum();
1345 } break;
1346 case CPDF_Object::ARRAY: {
1347 CPDF_Array* pKidsArray = pKids->AsArray();
1348 for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) {
1349 CPDF_Reference* pKid = ToReference(pKidsArray->GetElement(i));
1350 if (!pKid)
1351 continue;
1352
1353 PageNode* pNode = new PageNode();
1354 pPageNode->m_childNode.Add(pNode);
1355 pNode->m_dwPageNo = pKid->GetRefObjNum();
1356 }
1357 } break;
1358 default:
1359 break;
1360 }
1361 } else if (type == "Page") {
1362 pPageNode->m_type = PDF_PAGENODE_PAGE;
1363 } else {
1364 pPage->Release();
1365 m_docStatus = PDF_DATAAVAIL_ERROR;
1366 return FALSE;
1367 }
1368 pPage->Release();
1369 return TRUE;
1370 }
1371
1372 FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_DataAvail::PageNode& pageNodes,
1373 int32_t iPage,
1374 int32_t& iCount,
1375 IPDF_DataAvail::DownloadHints* pHints,
1376 int level) {
1377 if (level >= kMaxPageRecursionDepth)
1378 return FALSE;
1379
1380 int32_t iSize = pageNodes.m_childNode.GetSize();
1381 if (iSize <= 0 || iPage >= iSize) {
1382 m_docStatus = PDF_DATAAVAIL_ERROR;
1383 return FALSE;
1384 }
1385
1386 for (int32_t i = 0; i < iSize; ++i) {
1387 PageNode* pNode = pageNodes.m_childNode.GetAt(i);
1388 if (!pNode)
1389 continue;
1390
1391 switch (pNode->m_type) {
1392 case PDF_PAGENODE_UNKNOWN:
1393 if (!CheckUnkownPageNode(pNode->m_dwPageNo, pNode, pHints)) {
1394 return FALSE;
1395 }
1396 --i;
1397 break;
1398 case PDF_PAGENODE_PAGE:
1399 iCount++;
1400 if (iPage == iCount && m_pDocument)
1401 m_pDocument->m_PageList.SetAt(iPage, pNode->m_dwPageNo);
1402 break;
1403 case PDF_PAGENODE_PAGES:
1404 if (!CheckPageNode(*pNode, iPage, iCount, pHints, level + 1))
1405 return FALSE;
1406 break;
1407 case PDF_PAGENODE_ARRAY:
1408 if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints))
1409 return FALSE;
1410 --i;
1411 break;
1412 }
1413
1414 if (iPage == iCount) {
1415 m_docStatus = PDF_DATAAVAIL_DONE;
1416 return TRUE;
1417 }
1418 }
1419 return TRUE;
1420 }
1421
1422 FX_BOOL CPDF_DataAvail::LoadDocPage(int32_t iPage,
1423 IPDF_DataAvail::DownloadHints* pHints) {
1424 if (m_pDocument->GetPageCount() <= iPage ||
1425 m_pDocument->m_PageList.GetAt(iPage)) {
1426 m_docStatus = PDF_DATAAVAIL_DONE;
1427 return TRUE;
1428 }
1429
1430 if (m_pageNodes.m_type == PDF_PAGENODE_PAGE) {
1431 if (iPage == 0) {
1432 m_docStatus = PDF_DATAAVAIL_DONE;
1433 return TRUE;
1434 }
1435 m_docStatus = PDF_DATAAVAIL_ERROR;
1436 return TRUE;
1437 }
1438 int32_t iCount = -1;
1439 return CheckPageNode(m_pageNodes, iPage, iCount, pHints, 0);
1440 }
1441
1442 FX_BOOL CPDF_DataAvail::CheckPageCount(IPDF_DataAvail::DownloadHints* pHints) {
1443 FX_BOOL bExist = FALSE;
1444 CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist);
1445 if (!bExist) {
1446 m_docStatus = PDF_DATAAVAIL_ERROR;
1447 return FALSE;
1448 }
1449
1450 if (!pPages)
1451 return FALSE;
1452
1453 CPDF_Dictionary* pPagesDict = pPages->GetDict();
1454 if (!pPagesDict) {
1455 pPages->Release();
1456 m_docStatus = PDF_DATAAVAIL_ERROR;
1457 return FALSE;
1458 }
1459
1460 if (!pPagesDict->KeyExist("Kids")) {
1461 pPages->Release();
1462 return TRUE;
1463 }
1464
1465 int count = pPagesDict->GetIntegerBy("Count");
1466 if (count > 0) {
1467 pPages->Release();
1468 return TRUE;
1469 }
1470
1471 pPages->Release();
1472 return FALSE;
1473 }
1474
1475 FX_BOOL CPDF_DataAvail::LoadDocPages(IPDF_DataAvail::DownloadHints* pHints) {
1476 if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints))
1477 return FALSE;
1478
1479 if (CheckPageCount(pHints)) {
1480 m_docStatus = PDF_DATAAVAIL_PAGE;
1481 return TRUE;
1482 }
1483
1484 m_bTotalLoadPageTree = TRUE;
1485 return FALSE;
1486 }
1487
1488 FX_BOOL CPDF_DataAvail::LoadPages(IPDF_DataAvail::DownloadHints* pHints) {
1489 while (!m_bPagesTreeLoad) {
1490 if (!CheckPageStatus(pHints))
1491 return FALSE;
1492 }
1493
1494 if (m_bPagesLoad)
1495 return TRUE;
1496
1497 m_pDocument->LoadPages();
1498 return FALSE;
1499 }
1500
1501 IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedData(
1502 IPDF_DataAvail::DownloadHints* pHints) {
1503 if (m_bLinearedDataOK)
1504 return DataAvailable;
1505
1506 if (!m_bMainXRefLoadTried) {
1507 FX_SAFE_DWORD data_size = m_dwFileLen;
1508 data_size -= m_dwLastXRefOffset;
1509 if (!data_size.IsValid())
1510 return DataError;
1511
1512 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset,
1513 data_size.ValueOrDie())) {
1514 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie());
1515 return DataNotAvailable;
1516 }
1517
1518 CPDF_Parser::Error eRet =
1519 m_pDocument->GetParser()->LoadLinearizedMainXRefTable();
1520 m_bMainXRefLoadTried = TRUE;
1521 if (eRet != CPDF_Parser::SUCCESS)
1522 return DataError;
1523
1524 if (!PreparePageItem())
1525 return DataNotAvailable;
1526
1527 m_bMainXRefLoadedOK = TRUE;
1528 m_bLinearedDataOK = TRUE;
1529 }
1530
1531 return m_bLinearedDataOK ? DataAvailable : DataNotAvailable;
1532 }
1533
1534 FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage,
1535 IPDF_DataAvail::DownloadHints* pHints) {
1536 if (!m_objs_array.GetSize()) {
1537 m_objs_array.RemoveAll();
1538 m_ObjectSet.clear();
1539
1540 CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iPage);
1541 if (!pPageDict)
1542 return TRUE;
1543
1544 CPDF_Object* pAnnots = pPageDict->GetElement("Annots");
1545 if (!pAnnots)
1546 return TRUE;
1547
1548 CFX_ArrayTemplate<CPDF_Object*> obj_array;
1549 obj_array.Add(pAnnots);
1550
1551 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
1552 if (bRet)
1553 m_objs_array.RemoveAll();
1554
1555 return bRet;
1556 }
1557
1558 CFX_ArrayTemplate<CPDF_Object*> new_objs_array;
1559 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
1560 m_objs_array.RemoveAll();
1561 if (!bRet)
1562 m_objs_array.Append(new_objs_array);
1563
1564 return bRet;
1565 }
1566
1567 IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedFirstPage(
1568 int32_t iPage,
1569 IPDF_DataAvail::DownloadHints* pHints) {
1570 if (!m_bAnnotsLoad) {
1571 if (!CheckPageAnnots(iPage, pHints))
1572 return DataNotAvailable;
1573 m_bAnnotsLoad = TRUE;
1574 }
1575
1576 DocAvailStatus nRet = CheckLinearizedData(pHints);
1577 if (nRet == DataAvailable)
1578 m_bPageLoadedOK = FALSE;
1579 return nRet;
1580 }
1581
1582 FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary* pDict) {
1583 CFX_AutoRestorer<int> restorer(&s_CurrentDataAvailRecursionDepth);
1584 if (++s_CurrentDataAvailRecursionDepth > kMaxDataAvailRecursionDepth)
1585 return FALSE;
1586
1587 CPDF_Object* pParent = pDict->GetElement("Parent");
1588 if (!pParent)
1589 return FALSE;
1590
1591 CPDF_Dictionary* pParentDict = pParent->GetDict();
1592 if (!pParentDict)
1593 return FALSE;
1594
1595 CPDF_Object* pRet = pParentDict->GetElement("Resources");
1596 if (pRet) {
1597 m_pPageResource = pRet;
1598 return TRUE;
1599 }
1600
1601 return HaveResourceAncestor(pParentDict);
1602 }
1603
1604 IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail(
1605 int32_t iPage,
1606 IPDF_DataAvail::DownloadHints* pHints) {
1607 if (!m_pDocument)
1608 return DataError;
1609
1610 if (IsFirstCheck(iPage)) {
1611 m_bCurPageDictLoadOK = FALSE;
1612 m_bPageLoadedOK = FALSE;
1613 m_bAnnotsLoad = FALSE;
1614 m_bNeedDownLoadResource = FALSE;
1615 m_objs_array.RemoveAll();
1616 m_ObjectSet.clear();
1617 }
1618
1619 if (pdfium::ContainsKey(m_pagesLoadState, iPage))
1620 return DataAvailable;
1621
1622 if (m_bLinearized) {
1623 if ((FX_DWORD)iPage == m_dwFirstPageNo) {
1624 DocAvailStatus nRet = CheckLinearizedFirstPage(iPage, pHints);
1625 if (nRet == DataAvailable)
1626 m_pagesLoadState.insert(iPage);
1627 return nRet;
1628 }
1629
1630 DocAvailStatus nResult = CheckLinearizedData(pHints);
1631 if (nResult != DataAvailable)
1632 return nResult;
1633
1634 if (m_pHintTables) {
1635 nResult = m_pHintTables->CheckPage(iPage, pHints);
1636 if (nResult != DataAvailable)
1637 return nResult;
1638 m_pagesLoadState.insert(iPage);
1639 return DataAvailable;
1640 }
1641
1642 if (m_bMainXRefLoadedOK) {
1643 if (m_bTotalLoadPageTree) {
1644 if (!LoadPages(pHints))
1645 return DataNotAvailable;
1646 } else {
1647 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints))
1648 return DataNotAvailable;
1649 }
1650 } else {
1651 if (!LoadAllFile(pHints))
1652 return DataNotAvailable;
1653 m_pDocument->GetParser()->RebuildCrossRef();
1654 ResetFirstCheck(iPage);
1655 return DataAvailable;
1656 }
1657 } else {
1658 if (!m_bTotalLoadPageTree && !m_bCurPageDictLoadOK &&
1659 !CheckPage(iPage, pHints)) {
1660 return DataNotAvailable;
1661 }
1662 }
1663
1664 if (m_bHaveAcroForm && !m_bAcroFormLoad) {
1665 if (!CheckAcroFormSubObject(pHints))
1666 return DataNotAvailable;
1667 m_bAcroFormLoad = TRUE;
1668 }
1669
1670 if (!m_bPageLoadedOK) {
1671 if (!m_objs_array.GetSize()) {
1672 m_objs_array.RemoveAll();
1673 m_ObjectSet.clear();
1674
1675 m_pPageDict = m_pDocument->GetPage(iPage);
1676 if (!m_pPageDict) {
1677 ResetFirstCheck(iPage);
1678 return DataAvailable;
1679 }
1680
1681 CFX_ArrayTemplate<CPDF_Object*> obj_array;
1682 obj_array.Add(m_pPageDict);
1683 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);
1684 if (!bRet)
1685 return DataNotAvailable;
1686
1687 m_objs_array.RemoveAll();
1688 } else {
1689 CFX_ArrayTemplate<CPDF_Object*> new_objs_array;
1690 FX_BOOL bRet =
1691 IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
1692
1693 m_objs_array.RemoveAll();
1694 if (!bRet) {
1695 m_objs_array.Append(new_objs_array);
1696 return DataNotAvailable;
1697 }
1698 }
1699 m_bPageLoadedOK = TRUE;
1700 }
1701
1702 if (!m_bAnnotsLoad) {
1703 if (!CheckPageAnnots(iPage, pHints))
1704 return DataNotAvailable;
1705 m_bAnnotsLoad = TRUE;
1706 }
1707
1708 if (m_pPageDict && !m_bNeedDownLoadResource) {
1709 m_pPageResource = m_pPageDict->GetElement("Resources");
1710 if (!m_pPageResource)
1711 m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict);
1712 else
1713 m_bNeedDownLoadResource = TRUE;
1714 }
1715
1716 if (m_bNeedDownLoadResource) {
1717 FX_BOOL bRet = CheckResources(pHints);
1718 if (!bRet)
1719 return DataNotAvailable;
1720 m_bNeedDownLoadResource = FALSE;
1721 }
1722
1723 m_bPageLoadedOK = FALSE;
1724 m_bAnnotsLoad = FALSE;
1725 m_bCurPageDictLoadOK = FALSE;
1726
1727 ResetFirstCheck(iPage);
1728 m_pagesLoadState.insert(iPage);
1729 return DataAvailable;
1730 }
1731
1732 FX_BOOL CPDF_DataAvail::CheckResources(IPDF_DataAvail::DownloadHints* pHints) {
1733 if (!m_objs_array.GetSize()) {
1734 m_objs_array.RemoveAll();
1735 CFX_ArrayTemplate<CPDF_Object*> obj_array;
1736 obj_array.Add(m_pPageResource);
1737
1738 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);
1739 if (bRet)
1740 m_objs_array.RemoveAll();
1741 return bRet;
1742 }
1743
1744 CFX_ArrayTemplate<CPDF_Object*> new_objs_array;
1745 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
1746 m_objs_array.RemoveAll();
1747 if (!bRet)
1748 m_objs_array.Append(new_objs_array);
1749 return bRet;
1750 }
1751
1752 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos,
1753 FX_DWORD* pSize) {
1754 if (pPos)
1755 *pPos = m_dwLastXRefOffset;
1756 if (pSize)
1757 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset);
1758 }
1759
1760 int CPDF_DataAvail::GetPageCount() const {
1761 if (m_pLinearized) {
1762 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
1763 CPDF_Object* pObj = pDict ? pDict->GetElementValue("N") : nullptr;
1764 return pObj ? pObj->GetInteger() : 0;
1765 }
1766 return m_pDocument ? m_pDocument->GetPageCount() : 0;
1767 }
1768
1769 CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) {
1770 if (!m_pDocument || index < 0 || index >= GetPageCount())
1771 return nullptr;
1772
1773 if (m_pLinearized) {
1774 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
1775 CPDF_Object* pObj = pDict ? pDict->GetElementValue("P") : nullptr;
1776
1777 int pageNum = pObj ? pObj->GetInteger() : 0;
1778 if (m_pHintTables && index != pageNum) {
1779 FX_FILESIZE szPageStartPos = 0;
1780 FX_FILESIZE szPageLength = 0;
1781 FX_DWORD dwObjNum = 0;
1782 FX_BOOL bPagePosGot = m_pHintTables->GetPagePos(index, szPageStartPos,
1783 szPageLength, dwObjNum);
1784 if (!bPagePosGot)
1785 return nullptr;
1786
1787 m_syntaxParser.InitParser(m_pFileRead, (FX_DWORD)szPageStartPos);
1788 CPDF_Object* pPageDict = ParseIndirectObjectAt(0, dwObjNum, m_pDocument);
1789 if (!pPageDict)
1790 return nullptr;
1791
1792 if (!m_pDocument->InsertIndirectObject(dwObjNum, pPageDict))
1793 return nullptr;
1794 return pPageDict->GetDict();
1795 }
1796 }
1797 return m_pDocument->GetPage(index);
1798 }
1799
1800 IPDF_DataAvail::DocFormStatus CPDF_DataAvail::IsFormAvail(
1801 IPDF_DataAvail::DownloadHints* pHints) {
1802 if (!m_pDocument)
1803 return FormAvailable;
1804
1805 if (!m_bLinearizedFormParamLoad) {
1806 CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
1807 if (!pRoot)
1808 return FormAvailable;
1809
1810 CPDF_Object* pAcroForm = pRoot->GetElement("AcroForm");
1811 if (!pAcroForm)
1812 return FormNotExist;
1813
1814 DocAvailStatus nDocStatus = CheckLinearizedData(pHints);
1815 if (nDocStatus == DataError)
1816 return FormError;
1817 if (nDocStatus == DataNotAvailable)
1818 return FormNotAvailable;
1819
1820 if (!m_objs_array.GetSize())
1821 m_objs_array.Add(pAcroForm->GetDict());
1822 m_bLinearizedFormParamLoad = TRUE;
1823 }
1824
1825 CFX_ArrayTemplate<CPDF_Object*> new_objs_array;
1826 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
1827 m_objs_array.RemoveAll();
1828 if (!bRet) {
1829 m_objs_array.Append(new_objs_array);
1830 return FormNotAvailable;
1831 }
1832 return FormAvailable;
1833 }
1834
1835 CPDF_DataAvail::PageNode::PageNode() : m_type(PDF_PAGENODE_UNKNOWN) {}
1836
1837 CPDF_DataAvail::PageNode::~PageNode() {
1838 for (int32_t i = 0; i < m_childNode.GetSize(); ++i)
1839 delete m_childNode[i];
1840 m_childNode.RemoveAll();
1841 }
OLDNEW
« no previous file with comments | « core/src/fpdfapi/fpdf_parser/cpdf_data_avail.h ('k') | core/src/fpdfapi/fpdf_parser/cpdf_dictionary.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698