OLD | NEW |
---|---|
1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfapi/parser/cpdf_parser.h" | 7 #include "core/fpdfapi/parser/cpdf_parser.h" |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "core/fpdfapi/parser/cpdf_array.h" | 11 #include "core/fpdfapi/parser/cpdf_array.h" |
12 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" | 12 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" |
13 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 13 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
14 #include "core/fpdfapi/parser/cpdf_document.h" | 14 #include "core/fpdfapi/parser/cpdf_document.h" |
15 #include "core/fpdfapi/parser/cpdf_linearized.h" | |
15 #include "core/fpdfapi/parser/cpdf_number.h" | 16 #include "core/fpdfapi/parser/cpdf_number.h" |
16 #include "core/fpdfapi/parser/cpdf_reference.h" | 17 #include "core/fpdfapi/parser/cpdf_reference.h" |
17 #include "core/fpdfapi/parser/cpdf_security_handler.h" | 18 #include "core/fpdfapi/parser/cpdf_security_handler.h" |
18 #include "core/fpdfapi/parser/cpdf_stream.h" | 19 #include "core/fpdfapi/parser/cpdf_stream.h" |
19 #include "core/fpdfapi/parser/cpdf_stream_acc.h" | 20 #include "core/fpdfapi/parser/cpdf_stream_acc.h" |
20 #include "core/fpdfapi/parser/cpdf_syntax_parser.h" | 21 #include "core/fpdfapi/parser/cpdf_syntax_parser.h" |
21 #include "core/fpdfapi/parser/fpdf_parser_utility.h" | 22 #include "core/fpdfapi/parser/fpdf_parser_utility.h" |
22 #include "core/fxcrt/fx_ext.h" | 23 #include "core/fxcrt/fx_ext.h" |
23 #include "core/fxcrt/fx_safe_types.h" | 24 #include "core/fxcrt/fx_safe_types.h" |
24 #include "third_party/base/stl_util.h" | 25 #include "third_party/base/stl_util.h" |
(...skipping 22 matching lines...) Expand all Loading... | |
47 } // namespace | 48 } // namespace |
48 | 49 |
49 CPDF_Parser::CPDF_Parser() | 50 CPDF_Parser::CPDF_Parser() |
50 : m_pDocument(nullptr), | 51 : m_pDocument(nullptr), |
51 m_bHasParsed(false), | 52 m_bHasParsed(false), |
52 m_bOwnFileRead(true), | 53 m_bOwnFileRead(true), |
53 m_FileVersion(0), | 54 m_FileVersion(0), |
54 m_pTrailer(nullptr), | 55 m_pTrailer(nullptr), |
55 m_pEncryptDict(nullptr), | 56 m_pEncryptDict(nullptr), |
56 m_bVersionUpdated(false), | 57 m_bVersionUpdated(false), |
57 m_pLinearized(nullptr), | |
58 m_dwFirstPageNo(0), | |
59 m_dwXrefStartObjNum(0) { | 58 m_dwXrefStartObjNum(0) { |
60 m_pSyntax.reset(new CPDF_SyntaxParser); | 59 m_pSyntax.reset(new CPDF_SyntaxParser); |
61 } | 60 } |
62 | 61 |
63 CPDF_Parser::~CPDF_Parser() { | 62 CPDF_Parser::~CPDF_Parser() { |
64 if (m_pTrailer) | 63 if (m_pTrailer) |
65 m_pTrailer->Release(); | 64 m_pTrailer->Release(); |
66 | 65 |
67 ReleaseEncryptHandler(); | 66 ReleaseEncryptHandler(); |
68 SetEncryptDictionary(nullptr); | 67 SetEncryptDictionary(nullptr); |
69 | 68 |
70 if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) { | 69 if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) { |
71 m_pSyntax->m_pFileAccess->Release(); | 70 m_pSyntax->m_pFileAccess->Release(); |
72 m_pSyntax->m_pFileAccess = nullptr; | 71 m_pSyntax->m_pFileAccess = nullptr; |
73 } | 72 } |
74 | 73 |
75 for (CPDF_Dictionary* trailer : m_Trailers) { | 74 for (CPDF_Dictionary* trailer : m_Trailers) { |
76 if (trailer) | 75 if (trailer) |
77 trailer->Release(); | 76 trailer->Release(); |
78 } | 77 } |
79 | |
80 if (m_pLinearized) | |
81 m_pLinearized->Release(); | |
82 } | 78 } |
83 | 79 |
84 uint32_t CPDF_Parser::GetLastObjNum() const { | 80 uint32_t CPDF_Parser::GetLastObjNum() const { |
85 return m_ObjectInfo.empty() ? 0 : m_ObjectInfo.rbegin()->first; | 81 return m_ObjectInfo.empty() ? 0 : m_ObjectInfo.rbegin()->first; |
86 } | 82 } |
87 | 83 |
88 bool CPDF_Parser::IsValidObjectNumber(uint32_t objnum) const { | 84 bool CPDF_Parser::IsValidObjectNumber(uint32_t objnum) const { |
89 return !m_ObjectInfo.empty() && objnum <= m_ObjectInfo.rbegin()->first; | 85 return !m_ObjectInfo.empty() && objnum <= m_ObjectInfo.rbegin()->first; |
90 } | 86 } |
91 | 87 |
(...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1407 } | 1403 } |
1408 | 1404 |
1409 CPDF_Object* pObj = m_pSyntax->GetObjectForStrict(pObjList, objnum, gennum); | 1405 CPDF_Object* pObj = m_pSyntax->GetObjectForStrict(pObjList, objnum, gennum); |
1410 if (pResultPos) | 1406 if (pResultPos) |
1411 *pResultPos = m_pSyntax->m_Pos; | 1407 *pResultPos = m_pSyntax->m_Pos; |
1412 | 1408 |
1413 m_pSyntax->RestorePos(SavedPos); | 1409 m_pSyntax->RestorePos(SavedPos); |
1414 return pObj; | 1410 return pObj; |
1415 } | 1411 } |
1416 | 1412 |
1413 uint32_t CPDF_Parser::GetFirstPageNo() const { | |
1414 return m_pLinearized ? m_pLinearized->GetFirstPageNo() : 0; | |
1415 } | |
1416 | |
1417 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() { | 1417 CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() { |
1418 if (m_pSyntax->GetKeyword() != "trailer") | 1418 if (m_pSyntax->GetKeyword() != "trailer") |
1419 return nullptr; | 1419 return nullptr; |
1420 | 1420 |
1421 std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj( | 1421 std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj( |
1422 m_pSyntax->GetObject(m_pDocument, 0, 0, true)); | 1422 m_pSyntax->GetObject(m_pDocument, 0, 0, true)); |
1423 if (!ToDictionary(pObj.get())) | 1423 if (!ToDictionary(pObj.get())) |
1424 return nullptr; | 1424 return nullptr; |
1425 return pObj.release()->AsDictionary(); | 1425 return pObj.release()->AsDictionary(); |
1426 } | 1426 } |
(...skipping 26 matching lines...) Expand all Loading... | |
1453 word = m_pSyntax->GetNextWord(&bIsNumber); | 1453 word = m_pSyntax->GetNextWord(&bIsNumber); |
1454 if (!bIsNumber) | 1454 if (!bIsNumber) |
1455 return FALSE; | 1455 return FALSE; |
1456 | 1456 |
1457 uint32_t gennum = FXSYS_atoui(word.c_str()); | 1457 uint32_t gennum = FXSYS_atoui(word.c_str()); |
1458 if (m_pSyntax->GetKeyword() != "obj") { | 1458 if (m_pSyntax->GetKeyword() != "obj") { |
1459 m_pSyntax->RestorePos(SavedPos); | 1459 m_pSyntax->RestorePos(SavedPos); |
1460 return FALSE; | 1460 return FALSE; |
1461 } | 1461 } |
1462 | 1462 |
1463 m_pLinearized = m_pSyntax->GetObject(nullptr, objnum, gennum, true); | 1463 auto pLinearized = CPDF_Linearized::CreateForObject( |
Lei Zhang
2016/11/03 00:46:26
Do we want to directly assign to |m_pLinearized| h
snake
2016/11/03 01:39:27
What do you mean?
If we have not valid CPDF_Linear
Lei Zhang
2016/11/03 01:59:31
But with the IsValid() check that we just added, C
snake
2016/11/03 02:36:52
Done.
| |
1464 if (!m_pLinearized) | 1464 UniqueObject(m_pSyntax->GetObject(nullptr, objnum, gennum, true))); |
1465 if (!pLinearized || !pLinearized->IsValid()) | |
1465 return FALSE; | 1466 return FALSE; |
1466 | 1467 m_pLinearized = std::move(pLinearized); |
1467 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); | 1468 m_LastXRefOffset = m_pLinearized->GetLastXRefOffset(); |
1468 if (pDict && pDict->GetObjectFor("Linearized")) { | 1469 return TRUE; |
1469 m_pSyntax->GetNextWord(nullptr); | |
1470 | |
1471 CPDF_Object* pLen = pDict->GetObjectFor("L"); | |
1472 if (!pLen) { | |
1473 m_pLinearized->Release(); | |
1474 m_pLinearized = nullptr; | |
1475 return FALSE; | |
1476 } | |
1477 | |
1478 if (pLen->GetInteger() != (int)pFileAccess->GetSize()) | |
1479 return FALSE; | |
1480 | |
1481 if (CPDF_Number* pNo = ToNumber(pDict->GetObjectFor("P"))) | |
1482 m_dwFirstPageNo = pNo->GetInteger(); | |
1483 | |
1484 if (CPDF_Number* pTable = ToNumber(pDict->GetObjectFor("T"))) | |
1485 m_LastXRefOffset = pTable->GetInteger(); | |
1486 | |
1487 return TRUE; | |
1488 } | |
1489 m_pLinearized->Release(); | |
1490 m_pLinearized = nullptr; | |
1491 return FALSE; | |
1492 } | 1470 } |
1493 | 1471 |
1494 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( | 1472 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( |
1495 IFX_SeekableReadStream* pFileAccess, | 1473 IFX_SeekableReadStream* pFileAccess, |
1496 CPDF_Document* pDocument) { | 1474 CPDF_Document* pDocument) { |
1497 ASSERT(!m_bHasParsed); | 1475 ASSERT(!m_bHasParsed); |
1498 | 1476 |
1499 m_bXRefStream = FALSE; | 1477 m_bXRefStream = FALSE; |
1500 m_LastXRefOffset = 0; | 1478 m_LastXRefOffset = 0; |
1501 m_bOwnFileRead = true; | 1479 m_bOwnFileRead = true; |
1502 | 1480 |
1503 int32_t offset = GetHeaderOffset(pFileAccess); | 1481 int32_t offset = GetHeaderOffset(pFileAccess); |
1504 if (offset == -1) | 1482 if (offset == -1) |
1505 return FORMAT_ERROR; | 1483 return FORMAT_ERROR; |
1506 | 1484 |
1507 if (!IsLinearizedFile(pFileAccess, offset)) { | 1485 if (!IsLinearizedFile(pFileAccess, offset)) { |
1508 m_pSyntax->m_pFileAccess = nullptr; | 1486 m_pSyntax->m_pFileAccess = nullptr; |
1509 return StartParse(pFileAccess, std::move(pDocument)); | 1487 return StartParse(pFileAccess, std::move(pDocument)); |
1510 } | 1488 } |
1511 m_bHasParsed = true; | 1489 m_bHasParsed = true; |
1512 m_pDocument = pDocument; | 1490 m_pDocument = pDocument; |
1513 | 1491 |
1492 m_pSyntax->GetNextWord(nullptr); | |
1514 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); | 1493 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); |
1515 | 1494 |
1516 FX_BOOL bXRefRebuilt = FALSE; | 1495 FX_BOOL bXRefRebuilt = FALSE; |
1517 FX_BOOL bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE); | 1496 FX_BOOL bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE); |
1518 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { | 1497 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { |
1519 if (!RebuildCrossRef()) | 1498 if (!RebuildCrossRef()) |
1520 return FORMAT_ERROR; | 1499 return FORMAT_ERROR; |
1521 | 1500 |
1522 bXRefRebuilt = TRUE; | 1501 bXRefRebuilt = TRUE; |
1523 m_LastXRefOffset = 0; | 1502 m_LastXRefOffset = 0; |
1524 } | 1503 } |
1525 | 1504 |
1526 if (bLoadV4) { | 1505 if (bLoadV4) { |
1527 m_pTrailer = LoadTrailerV4(); | 1506 m_pTrailer = LoadTrailerV4(); |
1528 if (!m_pTrailer) | 1507 if (!m_pTrailer) |
1529 return SUCCESS; | 1508 return SUCCESS; |
1530 | 1509 |
1531 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 1510 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
1532 if (xrefsize > 0) | 1511 if (xrefsize > 0) |
1533 ShrinkObjectMap(xrefsize); | 1512 ShrinkObjectMap(xrefsize); |
1534 } | 1513 } |
1535 | 1514 |
1536 Error eRet = SetEncryptHandler(); | 1515 Error eRet = SetEncryptHandler(); |
1537 if (eRet != SUCCESS) | 1516 if (eRet != SUCCESS) |
1538 return eRet; | 1517 return eRet; |
1539 | 1518 |
1540 m_pDocument->LoadLinearizedDoc(m_pLinearized->GetDict()); | 1519 m_pDocument->LoadLinearizedDoc(m_pLinearized.get()); |
1541 if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { | 1520 if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { |
1542 if (bXRefRebuilt) | 1521 if (bXRefRebuilt) |
1543 return FORMAT_ERROR; | 1522 return FORMAT_ERROR; |
1544 | 1523 |
1545 ReleaseEncryptHandler(); | 1524 ReleaseEncryptHandler(); |
1546 if (!RebuildCrossRef()) | 1525 if (!RebuildCrossRef()) |
1547 return FORMAT_ERROR; | 1526 return FORMAT_ERROR; |
1548 | 1527 |
1549 eRet = SetEncryptHandler(); | 1528 eRet = SetEncryptHandler(); |
1550 if (eRet != SUCCESS) | 1529 if (eRet != SUCCESS) |
1551 return eRet; | 1530 return eRet; |
1552 | 1531 |
1553 m_pDocument->LoadLinearizedDoc(m_pLinearized->GetDict()); | 1532 m_pDocument->LoadLinearizedDoc(m_pLinearized.get()); |
1554 if (!m_pDocument->GetRoot()) | 1533 if (!m_pDocument->GetRoot()) |
1555 return FORMAT_ERROR; | 1534 return FORMAT_ERROR; |
1556 } | 1535 } |
1557 | 1536 |
1558 if (GetRootObjNum() == 0) { | 1537 if (GetRootObjNum() == 0) { |
1559 ReleaseEncryptHandler(); | 1538 ReleaseEncryptHandler(); |
1560 if (!RebuildCrossRef() || GetRootObjNum() == 0) | 1539 if (!RebuildCrossRef() || GetRootObjNum() == 0) |
1561 return FORMAT_ERROR; | 1540 return FORMAT_ERROR; |
1562 | 1541 |
1563 eRet = SetEncryptHandler(); | 1542 eRet = SetEncryptHandler(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1619 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && | 1598 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
1620 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { | 1599 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
1621 m_LastXRefOffset = 0; | 1600 m_LastXRefOffset = 0; |
1622 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1601 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
1623 return FORMAT_ERROR; | 1602 return FORMAT_ERROR; |
1624 } | 1603 } |
1625 | 1604 |
1626 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1605 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
1627 return SUCCESS; | 1606 return SUCCESS; |
1628 } | 1607 } |
OLD | NEW |