| 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 "parser_int.h" | 7 #include "parser_int.h" |
| 8 | 8 |
| 9 #include <algorithm> |
| 9 #include <memory> | 10 #include <memory> |
| 10 #include <set> | 11 #include <set> |
| 11 #include <utility> | 12 #include <utility> |
| 12 #include <vector> | 13 #include <vector> |
| 13 | 14 |
| 14 #include "core/include/fpdfapi/fpdf_module.h" | 15 #include "core/include/fpdfapi/fpdf_module.h" |
| 15 #include "core/include/fpdfapi/fpdf_page.h" | 16 #include "core/include/fpdfapi/fpdf_page.h" |
| 16 #include "core/include/fpdfapi/fpdf_parser.h" | 17 #include "core/include/fpdfapi/fpdf_parser.h" |
| 17 #include "core/include/fxcrt/fx_ext.h" | 18 #include "core/include/fxcrt/fx_ext.h" |
| 18 #include "core/include/fxcrt/fx_safe_types.h" | 19 #include "core/include/fxcrt/fx_safe_types.h" |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 m_ObjectInfo.clear(); | 613 m_ObjectInfo.clear(); |
| 613 m_V5Type.RemoveAll(); | 614 m_V5Type.RemoveAll(); |
| 614 m_SortedOffset.RemoveAll(); | 615 m_SortedOffset.RemoveAll(); |
| 615 m_ObjVersion.RemoveAll(); | 616 m_ObjVersion.RemoveAll(); |
| 616 if (m_pTrailer) { | 617 if (m_pTrailer) { |
| 617 m_pTrailer->Release(); | 618 m_pTrailer->Release(); |
| 618 m_pTrailer = NULL; | 619 m_pTrailer = NULL; |
| 619 } | 620 } |
| 620 int32_t status = 0; | 621 int32_t status = 0; |
| 621 int32_t inside_index = 0; | 622 int32_t inside_index = 0; |
| 622 FX_DWORD objnum = 0, gennum = 0; | 623 FX_DWORD objnum = 0; |
| 624 FX_DWORD gennum = 0; |
| 623 int32_t depth = 0; | 625 int32_t depth = 0; |
| 624 uint8_t* buffer = FX_Alloc(uint8_t, 4096); | 626 const FX_DWORD kBufferSize = 4096; |
| 627 std::vector<uint8_t> buffer(kBufferSize); |
| 625 FX_FILESIZE pos = m_Syntax.m_HeaderOffset; | 628 FX_FILESIZE pos = m_Syntax.m_HeaderOffset; |
| 626 FX_FILESIZE start_pos = 0, start_pos1 = 0; | 629 FX_FILESIZE start_pos = 0; |
| 627 FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1; | 630 FX_FILESIZE start_pos1 = 0; |
| 631 FX_FILESIZE last_obj = -1; |
| 632 FX_FILESIZE last_xref = -1; |
| 633 FX_FILESIZE last_trailer = -1; |
| 628 while (pos < m_Syntax.m_FileLen) { | 634 while (pos < m_Syntax.m_FileLen) { |
| 629 FX_BOOL bOverFlow = FALSE; | 635 const FX_FILESIZE saved_pos = pos; |
| 630 FX_DWORD size = (FX_DWORD)(m_Syntax.m_FileLen - pos); | 636 bool bOverFlow = false; |
| 631 if (size > 4096) { | 637 FX_DWORD size = std::min((FX_DWORD)(m_Syntax.m_FileLen - pos), kBufferSize); |
| 632 size = 4096; | 638 if (!m_Syntax.m_pFileAccess->ReadBlock(buffer.data(), pos, size)) |
| 633 } | |
| 634 if (!m_Syntax.m_pFileAccess->ReadBlock(buffer, pos, size)) { | |
| 635 break; | 639 break; |
| 636 } | 640 |
| 637 for (FX_DWORD i = 0; i < size; i++) { | 641 for (FX_DWORD i = 0; i < size; i++) { |
| 638 uint8_t byte = buffer[i]; | 642 uint8_t byte = buffer[i]; |
| 639 switch (status) { | 643 switch (status) { |
| 640 case 0: | 644 case 0: |
| 641 if (PDFCharIsWhitespace(byte)) | 645 if (PDFCharIsWhitespace(byte)) |
| 642 status = 1; | 646 status = 1; |
| 643 | 647 |
| 644 if (std::isdigit(byte)) { | 648 if (std::isdigit(byte)) { |
| 645 --i; | 649 --i; |
| 646 status = 1; | 650 status = 1; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 m_Syntax.RestorePos(obj_pos); | 804 m_Syntax.RestorePos(obj_pos); |
| 801 offset = m_Syntax.FindTag("obj", 0); | 805 offset = m_Syntax.FindTag("obj", 0); |
| 802 if (offset == -1) { | 806 if (offset == -1) { |
| 803 offset = 0; | 807 offset = 0; |
| 804 } else { | 808 } else { |
| 805 offset += 3; | 809 offset += 3; |
| 806 } | 810 } |
| 807 FX_FILESIZE nLen = obj_end - obj_pos - offset; | 811 FX_FILESIZE nLen = obj_end - obj_pos - offset; |
| 808 if ((FX_DWORD)nLen > size - i) { | 812 if ((FX_DWORD)nLen > size - i) { |
| 809 pos = obj_end + m_Syntax.m_HeaderOffset; | 813 pos = obj_end + m_Syntax.m_HeaderOffset; |
| 810 bOverFlow = TRUE; | 814 bOverFlow = true; |
| 811 } else { | 815 } else { |
| 812 i += (FX_DWORD)nLen; | 816 i += (FX_DWORD)nLen; |
| 813 } | 817 } |
| 814 if (!m_ObjectInfo.empty() && IsValidObjectNumber(objnum) && | 818 if (!m_ObjectInfo.empty() && IsValidObjectNumber(objnum) && |
| 815 m_ObjectInfo[objnum].pos) { | 819 m_ObjectInfo[objnum].pos) { |
| 816 if (pObject) { | 820 if (pObject) { |
| 817 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); | 821 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); |
| 818 m_ObjectInfo[objnum].pos = obj_pos; | 822 m_ObjectInfo[objnum].pos = obj_pos; |
| 819 m_ObjVersion.SetAt(objnum, (int16_t)gennum); | 823 m_ObjVersion.SetAt(objnum, (int16_t)gennum); |
| 820 if (oldgen != gennum) { | 824 if (oldgen != gennum) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 847 } else { | 851 } else { |
| 848 CPDF_Stream* pStream = pObj->AsStream(); | 852 CPDF_Stream* pStream = pObj->AsStream(); |
| 849 if (CPDF_Dictionary* pTrailer = | 853 if (CPDF_Dictionary* pTrailer = |
| 850 pStream ? pStream->GetDict() : pObj->AsDictionary()) { | 854 pStream ? pStream->GetDict() : pObj->AsDictionary()) { |
| 851 if (m_pTrailer) { | 855 if (m_pTrailer) { |
| 852 CPDF_Object* pRoot = pTrailer->GetElement("Root"); | 856 CPDF_Object* pRoot = pTrailer->GetElement("Root"); |
| 853 CPDF_Reference* pRef = ToReference(pRoot); | 857 CPDF_Reference* pRef = ToReference(pRoot); |
| 854 if (!pRoot || | 858 if (!pRoot || |
| 855 (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) && | 859 (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) && |
| 856 m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) { | 860 m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) { |
| 857 FX_POSITION pos = pTrailer->GetStartPos(); | 861 FX_POSITION trailer_pos = pTrailer->GetStartPos(); |
| 858 while (pos) { | 862 while (trailer_pos) { |
| 859 CFX_ByteString key; | 863 CFX_ByteString key; |
| 860 CPDF_Object* pElement = | 864 CPDF_Object* pElement = |
| 861 pTrailer->GetNextElement(pos, key); | 865 pTrailer->GetNextElement(trailer_pos, key); |
| 862 FX_DWORD dwObjNum = | 866 FX_DWORD dwObjNum = |
| 863 pElement ? pElement->GetObjNum() : 0; | 867 pElement ? pElement->GetObjNum() : 0; |
| 864 if (dwObjNum) { | 868 if (dwObjNum) { |
| 865 m_pTrailer->SetAtReference(key, m_pDocument, | 869 m_pTrailer->SetAtReference(key, m_pDocument, |
| 866 dwObjNum); | 870 dwObjNum); |
| 867 } else { | 871 } else { |
| 868 m_pTrailer->SetAt(key, pElement->Clone()); | 872 m_pTrailer->SetAt(key, pElement->Clone()); |
| 869 } | 873 } |
| 870 } | 874 } |
| 871 pObj->Release(); | 875 pObj->Release(); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 958 inside_index++; | 962 inside_index++; |
| 959 } | 963 } |
| 960 break; | 964 break; |
| 961 } | 965 } |
| 962 if (bOverFlow) { | 966 if (bOverFlow) { |
| 963 size = 0; | 967 size = 0; |
| 964 break; | 968 break; |
| 965 } | 969 } |
| 966 } | 970 } |
| 967 pos += size; | 971 pos += size; |
| 972 |
| 973 // If the position has not changed at all in a loop iteration, then break |
| 974 // out to prevent infinite looping. |
| 975 if (pos == saved_pos) |
| 976 break; |
| 968 } | 977 } |
| 969 if (last_xref != -1 && last_xref > last_obj) { | 978 if (last_xref != -1 && last_xref > last_obj) { |
| 970 last_trailer = last_xref; | 979 last_trailer = last_xref; |
| 971 } else if (last_trailer == -1 || last_xref < last_obj) { | 980 } else if (last_trailer == -1 || last_xref < last_obj) { |
| 972 last_trailer = m_Syntax.m_FileLen; | 981 last_trailer = m_Syntax.m_FileLen; |
| 973 } | 982 } |
| 974 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; | 983 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; |
| 975 void* pResult = | 984 void* pResult = |
| 976 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | 985 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 977 sizeof(FX_FILESIZE), CompareFileSize); | 986 sizeof(FX_FILESIZE), CompareFileSize); |
| 978 if (!pResult) { | 987 if (!pResult) { |
| 979 m_SortedOffset.Add(offset); | 988 m_SortedOffset.Add(offset); |
| 980 } | 989 } |
| 981 FX_Free(buffer); | |
| 982 return m_pTrailer && !m_ObjectInfo.empty(); | 990 return m_pTrailer && !m_ObjectInfo.empty(); |
| 983 } | 991 } |
| 984 | 992 |
| 985 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { | 993 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { |
| 986 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, *pos, 0, nullptr); | 994 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, *pos, 0, nullptr); |
| 987 if (!pObject) | 995 if (!pObject) |
| 988 return FALSE; | 996 return FALSE; |
| 989 if (m_pDocument) { | 997 if (m_pDocument) { |
| 990 FX_BOOL bInserted = FALSE; | 998 FX_BOOL bInserted = FALSE; |
| 991 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); | 999 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); |
| (...skipping 3997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4989 if (!m_pLinearizedDict) | 4997 if (!m_pLinearizedDict) |
| 4990 return -1; | 4998 return -1; |
| 4991 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); | 4999 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); |
| 4992 if (!pRange) | 5000 if (!pRange) |
| 4993 return -1; | 5001 return -1; |
| 4994 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | 5002 CPDF_Object* pStreamLen = pRange->GetElementValue(1); |
| 4995 if (!pStreamLen) | 5003 if (!pStreamLen) |
| 4996 return -1; | 5004 return -1; |
| 4997 return pStreamLen->GetInteger(); | 5005 return pStreamLen->GetInteger(); |
| 4998 } | 5006 } |
| OLD | NEW |