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 |