OLD | NEW |
---|---|
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "../../../../third_party/base/nonstd_unique_ptr.h" | |
11 #include "../../../include/fpdfapi/fpdf_module.h" | 12 #include "../../../include/fpdfapi/fpdf_module.h" |
12 #include "../../../include/fpdfapi/fpdf_page.h" | 13 #include "../../../include/fpdfapi/fpdf_page.h" |
13 #include "../../../include/fpdfapi/fpdf_parser.h" | 14 #include "../../../include/fpdfapi/fpdf_parser.h" |
14 #include "../../../include/fxcrt/fx_safe_types.h" | 15 #include "../../../include/fxcrt/fx_safe_types.h" |
15 #include "../fpdf_page/pageint.h" | 16 #include "../fpdf_page/pageint.h" |
16 | 17 |
18 namespace { | |
19 | |
20 int _CompareFileSize(const void* p1, const void* p2) { | |
Tom Sepez
2015/09/25 16:25:34
nit: can we lose the leading _ (it's namespaced no
Lei Zhang
2015/09/25 22:04:06
Done.
| |
21 FX_FILESIZE ret = (*(FX_FILESIZE*)p1) - (*(FX_FILESIZE*)p2); | |
Tom Sepez
2015/09/25 16:25:34
nit: overparenthesized.
Lei Zhang
2015/09/25 22:04:06
Done.
| |
22 if (ret == 0) | |
23 return 0; | |
24 return ret > 0 ? 1 : -1; | |
Tom Sepez
2015/09/25 16:25:35
Can you confirm if we're only passing this to qsor
Lei Zhang
2015/09/25 22:04:06
Done.
| |
25 } | |
26 | |
27 int32_t GetHeaderOffset(IFX_FileRead* pFile) { | |
28 const FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025); | |
29 const size_t kBufSize = 4; | |
30 uint8_t buf[kBufSize]; | |
31 int32_t offset = 0; | |
32 while (offset <= 1024) { | |
33 if (!pFile->ReadBlock(buf, offset, kBufSize)) | |
34 return -1; | |
35 | |
36 if (*(FX_DWORD*)buf == tag) | |
37 return offset; | |
38 | |
39 ++offset; | |
40 } | |
41 return -1; | |
42 } | |
43 | |
44 int32_t GetDirectInteger(CPDF_Dictionary* pDict, const CFX_ByteStringC& key) { | |
45 CPDF_Object* pObj = pDict->GetElement(key); | |
46 if (!pObj) | |
Tom Sepez
2015/09/25 16:25:35
nit: how about
if (pObj && pObj->GetType() == PD
Lei Zhang
2015/09/25 22:04:06
Done.
| |
47 return 0; | |
48 | |
49 if (pObj->GetType() == PDFOBJ_NUMBER) | |
50 return ((CPDF_Number*)pObj)->GetInteger(); | |
51 | |
52 return 0; | |
53 } | |
54 | |
55 bool CheckDirectType(CPDF_Dictionary* pDict, | |
56 const CFX_ByteStringC& key, | |
57 int32_t iType) { | |
58 CPDF_Object* pObj = pDict->GetElement(key); | |
59 return pObj ? (pObj->GetType() == iType) : true; | |
Tom Sepez
2015/09/25 16:25:35
nit: return !pObj || pObj->GetType() == itype;
Lei Zhang
2015/09/25 22:04:06
Done.
| |
60 } | |
61 | |
62 FX_DWORD _GetVarInt(const uint8_t* p, int32_t n) { | |
Tom Sepez
2015/09/25 16:25:35
nit: leading _
Lei Zhang
2015/09/25 22:04:06
Done.
| |
63 FX_DWORD result = 0; | |
64 for (int32_t i = 0; i < n; ++i) | |
65 result = result * 256 + p[i]; | |
66 return result; | |
67 } | |
68 | |
69 } // namespace | |
70 | |
17 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) { | 71 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) { |
18 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); | 72 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); |
19 if (!pType) { | 73 if (!pType) { |
20 pType = pDict->GetElementValue(FX_BSTRC("FT")); | 74 pType = pDict->GetElementValue(FX_BSTRC("FT")); |
21 if (!pType) { | 75 if (!pType) { |
22 return FALSE; | 76 return FALSE; |
23 } | 77 } |
24 } | 78 } |
25 if (pType->GetString() == FX_BSTRC("Sig")) { | 79 if (pType->GetString() == FX_BSTRC("Sig")) { |
26 return TRUE; | 80 return TRUE; |
27 } | 81 } |
28 return FALSE; | 82 return FALSE; |
29 } | 83 } |
30 static int _CompareFileSize(const void* p1, const void* p2) { | |
31 FX_FILESIZE ret = (*(FX_FILESIZE*)p1) - (*(FX_FILESIZE*)p2); | |
32 if (ret > 0) { | |
33 return 1; | |
34 } | |
35 if (ret < 0) { | |
36 return -1; | |
37 } | |
38 return 0; | |
39 } | |
40 | 84 |
41 CPDF_Parser::CPDF_Parser() { | 85 CPDF_Parser::CPDF_Parser() { |
42 m_pDocument = NULL; | 86 m_pDocument = NULL; |
43 m_pTrailer = NULL; | 87 m_pTrailer = NULL; |
44 m_pEncryptDict = NULL; | 88 m_pEncryptDict = NULL; |
45 m_pSecurityHandler = NULL; | 89 m_pSecurityHandler = NULL; |
46 m_pLinearized = NULL; | 90 m_pLinearized = NULL; |
47 m_dwFirstPageNo = 0; | 91 m_dwFirstPageNo = 0; |
48 m_dwXrefStartObjNum = 0; | 92 m_dwXrefStartObjNum = 0; |
49 m_bOwnFileRead = TRUE; | 93 m_bOwnFileRead = TRUE; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 for (int32_t i = 0; i < iLen; ++i) { | 136 for (int32_t i = 0; i < iLen; ++i) { |
93 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i)) | 137 if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i)) |
94 trailer->Release(); | 138 trailer->Release(); |
95 } | 139 } |
96 m_Trailers.RemoveAll(); | 140 m_Trailers.RemoveAll(); |
97 if (m_pLinearized) { | 141 if (m_pLinearized) { |
98 m_pLinearized->Release(); | 142 m_pLinearized->Release(); |
99 m_pLinearized = NULL; | 143 m_pLinearized = NULL; |
100 } | 144 } |
101 } | 145 } |
102 static int32_t GetHeaderOffset(IFX_FileRead* pFile) { | |
103 FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025); | |
104 uint8_t buf[4]; | |
105 int32_t offset = 0; | |
106 while (1) { | |
107 if (!pFile->ReadBlock(buf, offset, 4)) { | |
108 return -1; | |
109 } | |
110 if (*(FX_DWORD*)buf == tag) { | |
111 return offset; | |
112 } | |
113 offset++; | |
114 if (offset > 1024) { | |
115 return -1; | |
116 } | |
117 } | |
118 return -1; | |
119 } | |
120 CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler(); | 146 CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler(); |
121 CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*); | 147 CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*); |
122 FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, | 148 FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, |
123 FX_BOOL bReParse, | 149 FX_BOOL bReParse, |
124 FX_BOOL bOwnFileRead) { | 150 FX_BOOL bOwnFileRead) { |
125 CloseParser(bReParse); | 151 CloseParser(bReParse); |
126 m_bXRefStream = FALSE; | 152 m_bXRefStream = FALSE; |
127 m_LastXRefOffset = 0; | 153 m_LastXRefOffset = 0; |
128 m_bOwnFileRead = bOwnFileRead; | 154 m_bOwnFileRead = bOwnFileRead; |
129 int32_t offset = GetHeaderOffset(pFileAccess); | 155 int32_t offset = GetHeaderOffset(pFileAccess); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
306 return 0; | 332 return 0; |
307 } | 333 } |
308 if (m_V5Type[objnum] == 1) { | 334 if (m_V5Type[objnum] == 1) { |
309 return m_CrossRef[objnum]; | 335 return m_CrossRef[objnum]; |
310 } | 336 } |
311 if (m_V5Type[objnum] == 2) { | 337 if (m_V5Type[objnum] == 2) { |
312 return m_CrossRef[(int32_t)m_CrossRef[objnum]]; | 338 return m_CrossRef[(int32_t)m_CrossRef[objnum]]; |
313 } | 339 } |
314 return 0; | 340 return 0; |
315 } | 341 } |
316 static int32_t GetDirectInteger(CPDF_Dictionary* pDict, | 342 |
317 const CFX_ByteStringC& key) { | |
318 CPDF_Object* pObj = pDict->GetElement(key); | |
319 if (pObj == NULL) { | |
320 return 0; | |
321 } | |
322 if (pObj->GetType() == PDFOBJ_NUMBER) { | |
323 return ((CPDF_Number*)pObj)->GetInteger(); | |
324 } | |
325 return 0; | |
326 } | |
327 static FX_BOOL CheckDirectType(CPDF_Dictionary* pDict, | |
328 const CFX_ByteStringC& key, | |
329 int32_t iType) { | |
330 CPDF_Object* pObj = pDict->GetElement(key); | |
331 if (!pObj) { | |
332 return TRUE; | |
333 } | |
334 return pObj->GetType() == iType; | |
335 } | |
336 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { | 343 FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { |
337 if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) { | 344 if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) { |
338 return FALSE; | 345 return FALSE; |
339 } | 346 } |
340 m_pTrailer = LoadTrailerV4(); | 347 m_pTrailer = LoadTrailerV4(); |
341 if (m_pTrailer == NULL) { | 348 if (m_pTrailer == NULL) { |
342 return FALSE; | 349 return FALSE; |
343 } | 350 } |
344 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); | 351 int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); |
345 if (xrefsize <= 0 || xrefsize > (1 << 20)) { | 352 if (xrefsize <= 0 || xrefsize > (1 << 20)) { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
477 } | 484 } |
478 } | 485 } |
479 m_V5Type.SetAtGrow(objnum, 1); | 486 m_V5Type.SetAtGrow(objnum, 1); |
480 } | 487 } |
481 } | 488 } |
482 } | 489 } |
483 FX_Free(pBuf); | 490 FX_Free(pBuf); |
484 m_Syntax.RestorePos(SavedPos + count * recordsize); | 491 m_Syntax.RestorePos(SavedPos + count * recordsize); |
485 return TRUE; | 492 return TRUE; |
486 } | 493 } |
487 FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos, | 494 |
488 FX_FILESIZE streampos, | 495 bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos, |
489 FX_BOOL bSkip, | 496 FX_FILESIZE streampos, |
490 FX_BOOL bFirst) { | 497 FX_BOOL bSkip, |
498 FX_BOOL bFirst) { | |
491 m_Syntax.RestorePos(pos); | 499 m_Syntax.RestorePos(pos); |
492 if (m_Syntax.GetKeyword() != FX_BSTRC("xref")) { | 500 if (m_Syntax.GetKeyword() != FX_BSTRC("xref")) |
493 return FALSE; | 501 return false; |
494 } | 502 |
495 void* pResult = | 503 void* pResult = |
Tom Sepez
2015/09/25 16:25:35
nit: Local not needed
Lei Zhang
2015/09/25 22:04:06
Done.
| |
496 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | 504 FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
497 sizeof(FX_FILESIZE), _CompareFileSize); | 505 sizeof(FX_FILESIZE), _CompareFileSize); |
498 if (pResult == NULL) { | 506 if (!pResult) |
499 m_SortedOffset.Add(pos); | 507 m_SortedOffset.Add(pos); |
500 } | 508 |
501 if (streampos) { | 509 if (streampos) { |
502 void* pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(), | 510 void* pStreamResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(), |
Tom Sepez
2015/09/25 16:25:35
nit: Thanks for fixing the shadowing, but local st
Lei Zhang
2015/09/25 22:04:06
Done.
| |
503 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), | 511 m_SortedOffset.GetSize(), |
504 _CompareFileSize); | 512 sizeof(FX_FILESIZE), _CompareFileSize); |
505 if (pResult == NULL) { | 513 if (!pStreamResult) { |
506 m_SortedOffset.Add(streampos); | 514 m_SortedOffset.Add(streampos); |
507 } | 515 } |
508 } | 516 } |
517 | |
509 while (1) { | 518 while (1) { |
510 FX_FILESIZE SavedPos = m_Syntax.SavePos(); | 519 FX_FILESIZE SavedPos = m_Syntax.SavePos(); |
511 FX_BOOL bIsNumber; | 520 FX_BOOL bIsNumber; |
512 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); | 521 CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); |
513 if (word.IsEmpty()) { | 522 if (word.IsEmpty()) |
514 return FALSE; | 523 return false; |
515 } | 524 |
516 if (!bIsNumber) { | 525 if (!bIsNumber) { |
517 m_Syntax.RestorePos(SavedPos); | 526 m_Syntax.RestorePos(SavedPos); |
518 break; | 527 break; |
519 } | 528 } |
520 FX_DWORD start_objnum = FXSYS_atoi(word); | 529 FX_DWORD start_objnum = FXSYS_atoi(word); |
521 if (start_objnum >= (1 << 20)) { | 530 if (start_objnum >= (1 << 20)) |
522 return FALSE; | 531 return false; |
523 } | 532 |
524 FX_DWORD count = m_Syntax.GetDirectNum(); | 533 FX_DWORD count = m_Syntax.GetDirectNum(); |
525 m_Syntax.ToNextWord(); | 534 m_Syntax.ToNextWord(); |
526 SavedPos = m_Syntax.SavePos(); | 535 SavedPos = m_Syntax.SavePos(); |
527 FX_BOOL bFirstItem = FALSE; | 536 FX_BOOL bFirstItem = FALSE; |
528 int32_t recordsize = 20; | 537 int32_t recordsize = 20; |
529 if (bFirst) { | 538 if (bFirst) |
530 bFirstItem = TRUE; | 539 bFirstItem = TRUE; |
531 } | |
532 m_dwXrefStartObjNum = start_objnum; | 540 m_dwXrefStartObjNum = start_objnum; |
533 if (!bSkip) { | 541 if (!bSkip) { |
534 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); | 542 char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); |
535 pBuf[1024 * recordsize] = '\0'; | 543 pBuf[1024 * recordsize] = '\0'; |
536 int32_t nBlocks = count / 1024 + 1; | 544 int32_t nBlocks = count / 1024 + 1; |
537 FX_BOOL bFirstBlock = TRUE; | 545 FX_BOOL bFirstBlock = TRUE; |
538 for (int32_t block = 0; block < nBlocks; block++) { | 546 for (int32_t block = 0; block < nBlocks; block++) { |
539 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; | 547 int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; |
540 m_Syntax.ReadBlock((uint8_t*)pBuf, block_size * recordsize); | 548 m_Syntax.ReadBlock((uint8_t*)pBuf, block_size * recordsize); |
541 for (int32_t i = 0; i < block_size; i++) { | 549 for (int32_t i = 0; i < block_size; i++) { |
(...skipping 13 matching lines...) Expand all Loading... | |
555 } | 563 } |
556 } | 564 } |
557 m_CrossRef.SetAtGrow(objnum, 0); | 565 m_CrossRef.SetAtGrow(objnum, 0); |
558 m_V5Type.SetAtGrow(objnum, 0); | 566 m_V5Type.SetAtGrow(objnum, 0); |
559 } else { | 567 } else { |
560 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); | 568 FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); |
561 if (offset == 0) { | 569 if (offset == 0) { |
562 for (int32_t c = 0; c < 10; c++) { | 570 for (int32_t c = 0; c < 10; c++) { |
563 if (pEntry[c] < '0' || pEntry[c] > '9') { | 571 if (pEntry[c] < '0' || pEntry[c] > '9') { |
564 FX_Free(pBuf); | 572 FX_Free(pBuf); |
565 return FALSE; | 573 return false; |
566 } | 574 } |
567 } | 575 } |
568 } | 576 } |
569 m_CrossRef.SetAtGrow(objnum, offset); | 577 m_CrossRef.SetAtGrow(objnum, offset); |
570 int32_t version = FXSYS_atoi(pEntry + 11); | 578 int32_t version = FXSYS_atoi(pEntry + 11); |
571 if (version >= 1) { | 579 if (version >= 1) { |
572 m_bVersionUpdated = TRUE; | 580 m_bVersionUpdated = TRUE; |
573 } | 581 } |
574 m_ObjVersion.SetAtGrow(objnum, version); | 582 m_ObjVersion.SetAtGrow(objnum, version); |
575 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) { | 583 if (m_CrossRef[objnum] < m_Syntax.m_FileLen) { |
576 void* pResult = | 584 void* pRefResult = |
Tom Sepez
2015/09/25 16:25:35
nit: third time. Maybe a helper method.
Lei Zhang
2015/09/25 22:04:06
Done.
| |
577 FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(), | 585 FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(), |
578 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), | 586 m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), |
579 _CompareFileSize); | 587 _CompareFileSize); |
580 if (pResult == NULL) { | 588 if (!pRefResult) { |
581 m_SortedOffset.Add(m_CrossRef[objnum]); | 589 m_SortedOffset.Add(m_CrossRef[objnum]); |
582 } | 590 } |
583 } | 591 } |
584 m_V5Type.SetAtGrow(objnum, 1); | 592 m_V5Type.SetAtGrow(objnum, 1); |
585 } | 593 } |
586 if (bFirstBlock) { | 594 if (bFirstBlock) { |
587 bFirstBlock = FALSE; | 595 bFirstBlock = FALSE; |
588 } | 596 } |
589 } | 597 } |
590 } | 598 } |
591 FX_Free(pBuf); | 599 FX_Free(pBuf); |
592 } | 600 } |
593 m_Syntax.RestorePos(SavedPos + count * recordsize); | 601 m_Syntax.RestorePos(SavedPos + count * recordsize); |
594 } | 602 } |
595 if (streampos) | 603 return !streampos || LoadCrossRefV5(streampos, streampos, FALSE); |
596 if (!LoadCrossRefV5(streampos, streampos, FALSE)) { | |
597 return FALSE; | |
598 } | |
599 return TRUE; | |
600 } | 604 } |
605 | |
601 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) { | 606 FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) { |
602 if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) { | 607 if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) { |
603 return FALSE; | 608 return FALSE; |
604 } | 609 } |
605 while (xrefpos) | 610 while (xrefpos) |
606 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { | 611 if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { |
607 return FALSE; | 612 return FALSE; |
608 } | 613 } |
609 m_ObjectStreamMap.InitHashTable(101, FALSE); | 614 m_ObjectStreamMap.InitHashTable(101, FALSE); |
610 m_bXRefStream = TRUE; | 615 m_bXRefStream = TRUE; |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
990 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; | 995 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; |
991 void* pResult = | 996 void* pResult = |
992 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | 997 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
993 sizeof(FX_FILESIZE), _CompareFileSize); | 998 sizeof(FX_FILESIZE), _CompareFileSize); |
994 if (pResult == NULL) { | 999 if (pResult == NULL) { |
995 m_SortedOffset.Add(offset); | 1000 m_SortedOffset.Add(offset); |
996 } | 1001 } |
997 FX_Free(buffer); | 1002 FX_Free(buffer); |
998 return TRUE; | 1003 return TRUE; |
999 } | 1004 } |
1000 static FX_DWORD _GetVarInt(const uint8_t* p, int32_t n) { | 1005 |
1001 FX_DWORD result = 0; | |
1002 for (int32_t i = 0; i < n; i++) { | |
1003 result = result * 256 + p[i]; | |
1004 } | |
1005 return result; | |
1006 } | |
1007 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, | 1006 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, |
1008 FX_FILESIZE& prev, | 1007 FX_FILESIZE& prev, |
1009 FX_BOOL bMainXRef) { | 1008 FX_BOOL bMainXRef) { |
1010 CPDF_Stream* pStream = | 1009 CPDF_Stream* pStream = |
1011 (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos, 0, NULL); | 1010 (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos, 0, NULL); |
1012 if (!pStream) { | 1011 if (!pStream) { |
1013 return FALSE; | 1012 return FALSE; |
1014 } | 1013 } |
1015 if (m_pDocument) { | 1014 if (m_pDocument) { |
1016 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); | 1015 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1728 m_pFileBuf = NULL; | 1727 m_pFileBuf = NULL; |
1729 m_BufSize = CPDF_ModuleMgr::kFileBufSize; | 1728 m_BufSize = CPDF_ModuleMgr::kFileBufSize; |
1730 m_pFileBuf = NULL; | 1729 m_pFileBuf = NULL; |
1731 m_MetadataObjnum = 0; | 1730 m_MetadataObjnum = 0; |
1732 m_dwWordPos = 0; | 1731 m_dwWordPos = 0; |
1733 m_bFileStream = FALSE; | 1732 m_bFileStream = FALSE; |
1734 } | 1733 } |
1735 CPDF_SyntaxParser::~CPDF_SyntaxParser() { | 1734 CPDF_SyntaxParser::~CPDF_SyntaxParser() { |
1736 FX_Free(m_pFileBuf); | 1735 FX_Free(m_pFileBuf); |
1737 } | 1736 } |
1737 | |
1738 FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) { | 1738 FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) { |
1739 FX_FILESIZE save_pos = m_Pos; | 1739 CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos); |
Tom Sepez
2015/09/25 16:25:34
nice.
Lei Zhang
2015/09/25 22:04:06
Acknowledged.
| |
1740 m_Pos = pos; | 1740 m_Pos = pos; |
1741 FX_BOOL ret = GetNextChar(ch); | 1741 return GetNextChar(ch); |
1742 m_Pos = save_pos; | |
1743 return ret; | |
1744 } | 1742 } |
1743 | |
1745 FX_BOOL CPDF_SyntaxParser::GetNextChar(uint8_t& ch) { | 1744 FX_BOOL CPDF_SyntaxParser::GetNextChar(uint8_t& ch) { |
1746 FX_FILESIZE pos = m_Pos + m_HeaderOffset; | 1745 FX_FILESIZE pos = m_Pos + m_HeaderOffset; |
1747 if (pos >= m_FileLen) { | 1746 if (pos >= m_FileLen) { |
1748 return FALSE; | 1747 return FALSE; |
1749 } | 1748 } |
1750 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { | 1749 if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { |
1751 FX_FILESIZE read_pos = pos; | 1750 FX_FILESIZE read_pos = pos; |
1752 FX_DWORD read_size = m_BufSize; | 1751 FX_DWORD read_size = m_BufSize; |
1753 if ((FX_FILESIZE)read_size > m_FileLen) { | 1752 if ((FX_FILESIZE)read_size > m_FileLen) { |
1754 read_size = (FX_DWORD)m_FileLen; | 1753 read_size = (FX_DWORD)m_FileLen; |
(...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2693 } else { | 2692 } else { |
2694 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1; | 2693 offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1; |
2695 pos--; | 2694 pos--; |
2696 } | 2695 } |
2697 if (pos < 0) { | 2696 if (pos < 0) { |
2698 return FALSE; | 2697 return FALSE; |
2699 } | 2698 } |
2700 } | 2699 } |
2701 return FALSE; | 2700 return FALSE; |
2702 } | 2701 } |
2702 | |
2703 struct _SearchTagRecord { | 2703 struct _SearchTagRecord { |
2704 const uint8_t* m_pTag; | 2704 const uint8_t* m_pTag; |
2705 FX_DWORD m_Len; | 2705 FX_DWORD m_Len; |
2706 FX_DWORD m_Offset; | 2706 FX_DWORD m_Offset; |
2707 }; | 2707 }; |
2708 | |
2708 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags, | 2709 int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags, |
2709 FX_BOOL bWholeWord, | 2710 FX_BOOL bWholeWord, |
2710 FX_FILESIZE limit) { | 2711 FX_FILESIZE limit) { |
2711 int32_t ntags = 1, i; | 2712 int32_t ntags = 1; |
2712 for (i = 0; i < tags.GetLength(); i++) | 2713 for (int i = 0; i < tags.GetLength(); ++i) { |
2713 if (tags[i] == 0) { | 2714 if (tags[i] == 0) { |
2714 ntags++; | 2715 ++ntags; |
2715 } | 2716 } |
2716 _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags); | 2717 } |
2717 FX_DWORD start = 0, itag = 0, max_len = 0; | 2718 |
2718 for (i = 0; i <= tags.GetLength(); i++) { | 2719 std::vector<_SearchTagRecord> patterns(ntags); |
2720 FX_DWORD start = 0; | |
2721 FX_DWORD itag = 0; | |
2722 FX_DWORD max_len = 0; | |
2723 for (int i = 0; i <= tags.GetLength(); ++i) { | |
2719 if (tags[i] == 0) { | 2724 if (tags[i] == 0) { |
2720 FX_DWORD len = i - start; | 2725 FX_DWORD len = i - start; |
2721 if (len > max_len) { | 2726 max_len = std::max(len, max_len); |
2722 max_len = len; | 2727 patterns[itag].m_pTag = tags.GetPtr() + start; |
2723 } | 2728 patterns[itag].m_Len = len; |
2724 pPatterns[itag].m_pTag = tags.GetPtr() + start; | 2729 patterns[itag].m_Offset = 0; |
2725 pPatterns[itag].m_Len = len; | |
2726 pPatterns[itag].m_Offset = 0; | |
2727 start = i + 1; | 2730 start = i + 1; |
2728 itag++; | 2731 ++itag; |
2729 } | 2732 } |
2730 } | 2733 } |
2731 FX_FILESIZE pos = m_Pos; | 2734 |
2732 uint8_t byte; | 2735 const FX_FILESIZE pos_limit = m_Pos + limit; |
2733 GetCharAt(pos++, byte); | 2736 for (FX_FILESIZE pos = m_Pos; limit && pos >= pos_limit; ++pos) { |
Tom Sepez
2015/09/25 16:25:35
I think you need to negate your test.
Lei Zhang
2015/09/25 22:04:06
Done.
| |
2734 int32_t found = -1; | 2737 uint8_t byte; |
2735 while (1) { | 2738 if (!GetCharAt(pos, byte)) |
2736 for (i = 0; i < ntags; i++) { | 2739 break; |
2737 if (pPatterns[i].m_pTag[pPatterns[i].m_Offset] == byte) { | 2740 |
2738 pPatterns[i].m_Offset++; | 2741 for (int i = 0; i < ntags; ++i) { |
2739 if (pPatterns[i].m_Offset == pPatterns[i].m_Len) { | 2742 _SearchTagRecord& pat = patterns[i]; |
2740 if (!bWholeWord || | 2743 if (pat.m_pTag[pat.m_Offset] != byte) { |
2741 IsWholeWord(pos - pPatterns[i].m_Len, limit, pPatterns[i].m_pTag, | 2744 pat.m_Offset = (pat.m_pTag[0] == byte) ? 1 : 0; |
2742 pPatterns[i].m_Len)) { | 2745 continue; |
2743 found = i; | |
2744 goto end; | |
2745 } else { | |
2746 if (pPatterns[i].m_pTag[0] == byte) { | |
2747 pPatterns[i].m_Offset = 1; | |
2748 } else { | |
2749 pPatterns[i].m_Offset = 0; | |
2750 } | |
2751 } | |
2752 } | |
2753 } else { | |
2754 if (pPatterns[i].m_pTag[0] == byte) { | |
2755 pPatterns[i].m_Offset = 1; | |
2756 } else { | |
2757 pPatterns[i].m_Offset = 0; | |
2758 } | |
2759 } | 2746 } |
2747 | |
2748 ++pat.m_Offset; | |
2749 if (pat.m_Offset != pat.m_Len) | |
2750 continue; | |
2751 | |
2752 if (!bWholeWord || | |
2753 IsWholeWord(pos - pat.m_Len, limit, pat.m_pTag, pat.m_Len)) { | |
2754 return i; | |
2755 } | |
2756 | |
2757 pat.m_Offset = (pat.m_pTag[0] == byte) ? 1 : 0; | |
2760 } | 2758 } |
2761 if (limit && pos >= m_Pos + limit) { | |
2762 goto end; | |
2763 } | |
2764 if (!GetCharAt(pos, byte)) { | |
2765 goto end; | |
2766 } | |
2767 pos++; | |
2768 } | 2759 } |
2769 end: | 2760 return -1; |
2770 FX_Free(pPatterns); | |
2771 return found; | |
2772 } | 2761 } |
2762 | |
2773 FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag, | 2763 FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag, |
2774 FX_FILESIZE limit) { | 2764 FX_FILESIZE limit) { |
2775 int32_t taglen = tag.GetLength(); | 2765 int32_t taglen = tag.GetLength(); |
2776 int32_t match = 0; | 2766 int32_t match = 0; |
2777 limit += m_Pos; | 2767 limit += m_Pos; |
2778 FX_FILESIZE startpos = m_Pos; | 2768 FX_FILESIZE startpos = m_Pos; |
2779 while (1) { | 2769 while (1) { |
2780 uint8_t ch; | 2770 uint8_t ch; |
2781 if (!GetNextChar(ch)) { | 2771 if (!GetNextChar(ch)) { |
2782 return -1; | 2772 return -1; |
(...skipping 24 matching lines...) Expand all Loading... | |
2807 break; | 2797 break; |
2808 } | 2798 } |
2809 } | 2799 } |
2810 } | 2800 } |
2811 | 2801 |
2812 class CPDF_DataAvail final : public IPDF_DataAvail { | 2802 class CPDF_DataAvail final : public IPDF_DataAvail { |
2813 public: | 2803 public: |
2814 CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); | 2804 CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); |
2815 ~CPDF_DataAvail() override; | 2805 ~CPDF_DataAvail() override; |
2816 | 2806 |
2817 virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; | 2807 FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; |
2818 | 2808 |
2819 virtual void SetDocument(CPDF_Document* pDoc) override; | 2809 void SetDocument(CPDF_Document* pDoc) override; |
2820 | 2810 |
2821 virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; | 2811 FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; |
2822 | 2812 |
2823 virtual int32_t IsFormAvail(IFX_DownloadHints* pHints) override; | 2813 int32_t IsFormAvail(IFX_DownloadHints* pHints) override; |
2824 | 2814 |
2825 virtual int32_t IsLinearizedPDF() override; | 2815 int32_t IsLinearizedPDF() override; |
2826 | 2816 |
2827 virtual FX_BOOL IsLinearized() override { return m_bLinearized; } | 2817 FX_BOOL IsLinearized() override { return m_bLinearized; } |
2828 | 2818 |
2829 virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, | 2819 void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, FX_DWORD* pSize) override; |
2830 FX_DWORD* pSize) override; | |
2831 | 2820 |
2832 protected: | 2821 protected: |
2833 static const int kMaxDataAvailRecursionDepth = 64; | 2822 static const int kMaxDataAvailRecursionDepth = 64; |
2834 static int s_CurrentDataAvailRecursionDepth; | 2823 static int s_CurrentDataAvailRecursionDepth; |
2835 | 2824 |
2836 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); | 2825 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); |
2837 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, | 2826 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, |
2838 FX_BOOL bParsePage, | 2827 FX_BOOL bParsePage, |
2839 IFX_DownloadHints* pHints, | 2828 IFX_DownloadHints* pHints, |
2840 CFX_PtrArray& ret_array); | 2829 CFX_PtrArray& ret_array); |
(...skipping 1842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4683 return FALSE; | 4672 return FALSE; |
4684 } | 4673 } |
4685 CPDF_PageNode::~CPDF_PageNode() { | 4674 CPDF_PageNode::~CPDF_PageNode() { |
4686 int32_t iSize = m_childNode.GetSize(); | 4675 int32_t iSize = m_childNode.GetSize(); |
4687 for (int32_t i = 0; i < iSize; ++i) { | 4676 for (int32_t i = 0; i < iSize; ++i) { |
4688 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; | 4677 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; |
4689 delete pNode; | 4678 delete pNode; |
4690 } | 4679 } |
4691 m_childNode.RemoveAll(); | 4680 m_childNode.RemoveAll(); |
4692 } | 4681 } |
OLD | NEW |