| 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), | 58 m_dwFirstPageNo(0), |
| 59 m_dwXrefStartObjNum(0) { | 59 m_dwXrefStartObjNum(0) { |
| 60 m_pSyntax.reset(new CPDF_SyntaxParser); | 60 m_pSyntax.reset(new CPDF_SyntaxParser); |
| 61 } | 61 } |
| 62 | 62 |
| 63 CPDF_Parser::~CPDF_Parser() { | 63 CPDF_Parser::~CPDF_Parser() { |
| 64 if (m_pTrailer) | 64 if (m_pTrailer) |
| 65 m_pTrailer->Release(); | 65 m_pTrailer->Release(); |
| 66 | 66 |
| 67 ReleaseEncryptHandler(); | 67 ReleaseEncryptHandler(); |
| 68 SetEncryptDictionary(nullptr); | 68 SetEncryptDictionary(nullptr); |
| 69 | 69 |
| 70 if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) { | 70 if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) { |
| 71 m_pSyntax->m_pFileAccess->Release(); | 71 m_pSyntax->m_pFileAccess->Release(); |
| 72 m_pSyntax->m_pFileAccess = nullptr; | 72 m_pSyntax->m_pFileAccess = nullptr; |
| 73 } | 73 } |
| 74 | 74 |
| 75 for (CPDF_Dictionary* trailer : m_Trailers) { | 75 for (CPDF_Dictionary* trailer : m_Trailers) { |
| 76 if (trailer) | 76 if (trailer) |
| 77 trailer->Release(); | 77 trailer->Release(); |
| 78 } | 78 } |
| 79 | |
| 80 if (m_pLinearized) | |
| 81 m_pLinearized->Release(); | |
| 82 } | 79 } |
| 83 | 80 |
| 84 uint32_t CPDF_Parser::GetLastObjNum() const { | 81 uint32_t CPDF_Parser::GetLastObjNum() const { |
| 85 return m_ObjectInfo.empty() ? 0 : m_ObjectInfo.rbegin()->first; | 82 return m_ObjectInfo.empty() ? 0 : m_ObjectInfo.rbegin()->first; |
| 86 } | 83 } |
| 87 | 84 |
| 88 bool CPDF_Parser::IsValidObjectNumber(uint32_t objnum) const { | 85 bool CPDF_Parser::IsValidObjectNumber(uint32_t objnum) const { |
| 89 return !m_ObjectInfo.empty() && objnum <= m_ObjectInfo.rbegin()->first; | 86 return !m_ObjectInfo.empty() && objnum <= m_ObjectInfo.rbegin()->first; |
| 90 } | 87 } |
| 91 | 88 |
| (...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 word = m_pSyntax->GetNextWord(&bIsNumber); | 1450 word = m_pSyntax->GetNextWord(&bIsNumber); |
| 1454 if (!bIsNumber) | 1451 if (!bIsNumber) |
| 1455 return FALSE; | 1452 return FALSE; |
| 1456 | 1453 |
| 1457 uint32_t gennum = FXSYS_atoui(word.c_str()); | 1454 uint32_t gennum = FXSYS_atoui(word.c_str()); |
| 1458 if (m_pSyntax->GetKeyword() != "obj") { | 1455 if (m_pSyntax->GetKeyword() != "obj") { |
| 1459 m_pSyntax->RestorePos(SavedPos); | 1456 m_pSyntax->RestorePos(SavedPos); |
| 1460 return FALSE; | 1457 return FALSE; |
| 1461 } | 1458 } |
| 1462 | 1459 |
| 1463 m_pLinearized = m_pSyntax->GetObject(nullptr, objnum, gennum, true); | 1460 m_pLinearized = CPDF_Linearized::CreateForObject( |
| 1461 UniqueObject(m_pSyntax->GetObject(nullptr, objnum, gennum, true))); |
| 1464 if (!m_pLinearized) | 1462 if (!m_pLinearized) |
| 1465 return FALSE; | 1463 return FALSE; |
| 1466 | 1464 m_dwFirstPageNo = m_pLinearized->GetFirstPageNo(); |
| 1467 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); | 1465 m_LastXRefOffset = m_pLinearized->GetLastXRefOffset(); |
| 1468 if (pDict && pDict->GetObjectFor("Linearized")) { | 1466 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 } | 1467 } |
| 1493 | 1468 |
| 1494 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( | 1469 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( |
| 1495 IFX_SeekableReadStream* pFileAccess, | 1470 IFX_SeekableReadStream* pFileAccess, |
| 1496 CPDF_Document* pDocument) { | 1471 CPDF_Document* pDocument) { |
| 1497 ASSERT(!m_bHasParsed); | 1472 ASSERT(!m_bHasParsed); |
| 1498 | 1473 |
| 1499 m_bXRefStream = FALSE; | 1474 m_bXRefStream = FALSE; |
| 1500 m_LastXRefOffset = 0; | 1475 m_LastXRefOffset = 0; |
| 1501 m_bOwnFileRead = true; | 1476 m_bOwnFileRead = true; |
| 1502 | 1477 |
| 1503 int32_t offset = GetHeaderOffset(pFileAccess); | 1478 int32_t offset = GetHeaderOffset(pFileAccess); |
| 1504 if (offset == -1) | 1479 if (offset == -1) |
| 1505 return FORMAT_ERROR; | 1480 return FORMAT_ERROR; |
| 1506 | 1481 |
| 1507 if (!IsLinearizedFile(pFileAccess, offset)) { | 1482 if (!IsLinearizedFile(pFileAccess, offset)) { |
| 1508 m_pSyntax->m_pFileAccess = nullptr; | 1483 m_pSyntax->m_pFileAccess = nullptr; |
| 1509 return StartParse(pFileAccess, std::move(pDocument)); | 1484 return StartParse(pFileAccess, std::move(pDocument)); |
| 1510 } | 1485 } |
| 1511 m_bHasParsed = true; | 1486 m_bHasParsed = true; |
| 1512 m_pDocument = pDocument; | 1487 m_pDocument = pDocument; |
| 1513 | 1488 |
| 1489 m_pSyntax->GetNextWord(nullptr); |
| 1514 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); | 1490 FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos(); |
| 1515 | 1491 |
| 1516 FX_BOOL bXRefRebuilt = FALSE; | 1492 FX_BOOL bXRefRebuilt = FALSE; |
| 1517 FX_BOOL bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE); | 1493 FX_BOOL bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE); |
| 1518 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { | 1494 if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) { |
| 1519 if (!RebuildCrossRef()) | 1495 if (!RebuildCrossRef()) |
| 1520 return FORMAT_ERROR; | 1496 return FORMAT_ERROR; |
| 1521 | 1497 |
| 1522 bXRefRebuilt = TRUE; | 1498 bXRefRebuilt = TRUE; |
| 1523 m_LastXRefOffset = 0; | 1499 m_LastXRefOffset = 0; |
| 1524 } | 1500 } |
| 1525 | 1501 |
| 1526 if (bLoadV4) { | 1502 if (bLoadV4) { |
| 1527 m_pTrailer = LoadTrailerV4(); | 1503 m_pTrailer = LoadTrailerV4(); |
| 1528 if (!m_pTrailer) | 1504 if (!m_pTrailer) |
| 1529 return SUCCESS; | 1505 return SUCCESS; |
| 1530 | 1506 |
| 1531 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); | 1507 int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size"); |
| 1532 if (xrefsize > 0) | 1508 if (xrefsize > 0) |
| 1533 ShrinkObjectMap(xrefsize); | 1509 ShrinkObjectMap(xrefsize); |
| 1534 } | 1510 } |
| 1535 | 1511 |
| 1536 Error eRet = SetEncryptHandler(); | 1512 Error eRet = SetEncryptHandler(); |
| 1537 if (eRet != SUCCESS) | 1513 if (eRet != SUCCESS) |
| 1538 return eRet; | 1514 return eRet; |
| 1539 | 1515 |
| 1540 m_pDocument->LoadLinearizedDoc(m_pLinearized->GetDict()); | 1516 m_pDocument->LoadLinearizedDoc(m_pLinearized.get()); |
| 1541 if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { | 1517 if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) { |
| 1542 if (bXRefRebuilt) | 1518 if (bXRefRebuilt) |
| 1543 return FORMAT_ERROR; | 1519 return FORMAT_ERROR; |
| 1544 | 1520 |
| 1545 ReleaseEncryptHandler(); | 1521 ReleaseEncryptHandler(); |
| 1546 if (!RebuildCrossRef()) | 1522 if (!RebuildCrossRef()) |
| 1547 return FORMAT_ERROR; | 1523 return FORMAT_ERROR; |
| 1548 | 1524 |
| 1549 eRet = SetEncryptHandler(); | 1525 eRet = SetEncryptHandler(); |
| 1550 if (eRet != SUCCESS) | 1526 if (eRet != SUCCESS) |
| 1551 return eRet; | 1527 return eRet; |
| 1552 | 1528 |
| 1553 m_pDocument->LoadLinearizedDoc(m_pLinearized->GetDict()); | 1529 m_pDocument->LoadLinearizedDoc(m_pLinearized.get()); |
| 1554 if (!m_pDocument->GetRoot()) | 1530 if (!m_pDocument->GetRoot()) |
| 1555 return FORMAT_ERROR; | 1531 return FORMAT_ERROR; |
| 1556 } | 1532 } |
| 1557 | 1533 |
| 1558 if (GetRootObjNum() == 0) { | 1534 if (GetRootObjNum() == 0) { |
| 1559 ReleaseEncryptHandler(); | 1535 ReleaseEncryptHandler(); |
| 1560 if (!RebuildCrossRef() || GetRootObjNum() == 0) | 1536 if (!RebuildCrossRef() || GetRootObjNum() == 0) |
| 1561 return FORMAT_ERROR; | 1537 return FORMAT_ERROR; |
| 1562 | 1538 |
| 1563 eRet = SetEncryptHandler(); | 1539 eRet = SetEncryptHandler(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && | 1595 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
| 1620 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { | 1596 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
| 1621 m_LastXRefOffset = 0; | 1597 m_LastXRefOffset = 0; |
| 1622 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1598 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1623 return FORMAT_ERROR; | 1599 return FORMAT_ERROR; |
| 1624 } | 1600 } |
| 1625 | 1601 |
| 1626 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1602 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
| 1627 return SUCCESS; | 1603 return SUCCESS; |
| 1628 } | 1604 } |
| OLD | NEW |