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

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

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

Powered by Google App Engine
This is Rietveld 408576698