Chromium Code Reviews| 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 <set> | 10 #include <set> |
| 10 #include <utility> | 11 #include <utility> |
| 11 #include <vector> | 12 #include <vector> |
| 12 | 13 |
| 13 #include "core/include/fpdfapi/fpdf_module.h" | 14 #include "core/include/fpdfapi/fpdf_module.h" |
| 14 #include "core/include/fpdfapi/fpdf_page.h" | 15 #include "core/include/fpdfapi/fpdf_page.h" |
| 15 #include "core/include/fpdfapi/fpdf_parser.h" | 16 #include "core/include/fpdfapi/fpdf_parser.h" |
| 16 #include "core/include/fxcrt/fx_ext.h" | 17 #include "core/include/fxcrt/fx_ext.h" |
| 17 #include "core/include/fxcrt/fx_safe_types.h" | 18 #include "core/include/fxcrt/fx_safe_types.h" |
| 18 #include "core/src/fpdfapi/fpdf_page/pageint.h" | 19 #include "core/src/fpdfapi/fpdf_page/pageint.h" |
| (...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 608 m_ObjectInfo.clear(); | 609 m_ObjectInfo.clear(); |
| 609 m_V5Type.RemoveAll(); | 610 m_V5Type.RemoveAll(); |
| 610 m_SortedOffset.RemoveAll(); | 611 m_SortedOffset.RemoveAll(); |
| 611 m_ObjVersion.RemoveAll(); | 612 m_ObjVersion.RemoveAll(); |
| 612 if (m_pTrailer) { | 613 if (m_pTrailer) { |
| 613 m_pTrailer->Release(); | 614 m_pTrailer->Release(); |
| 614 m_pTrailer = NULL; | 615 m_pTrailer = NULL; |
| 615 } | 616 } |
| 616 int32_t status = 0; | 617 int32_t status = 0; |
| 617 int32_t inside_index = 0; | 618 int32_t inside_index = 0; |
| 618 FX_DWORD objnum = 0, gennum = 0; | 619 FX_DWORD objnum = 0; |
| 620 FX_DWORD gennum = 0; | |
| 619 int32_t depth = 0; | 621 int32_t depth = 0; |
| 620 uint8_t* buffer = FX_Alloc(uint8_t, 4096); | 622 const FX_DWORD kBufferSize = 4096; |
| 623 std::vector<uint8_t> buffer(kBufferSize); | |
| 621 FX_FILESIZE pos = m_Syntax.m_HeaderOffset; | 624 FX_FILESIZE pos = m_Syntax.m_HeaderOffset; |
| 622 FX_FILESIZE start_pos = 0, start_pos1 = 0; | 625 FX_FILESIZE start_pos = 0, start_pos1 = 0; |
| 623 FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1; | 626 FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1; |
| 624 while (pos < m_Syntax.m_FileLen) { | 627 while (pos < m_Syntax.m_FileLen) { |
| 625 FX_BOOL bOverFlow = FALSE; | 628 bool bOverFlow = false; |
| 626 FX_DWORD size = (FX_DWORD)(m_Syntax.m_FileLen - pos); | 629 FX_DWORD size = std::min((FX_DWORD)(m_Syntax.m_FileLen - pos), kBufferSize); |
| 627 if (size > 4096) { | 630 if (!m_Syntax.m_pFileAccess->ReadBlock(buffer.data(), pos, size)) |
| 628 size = 4096; | |
| 629 } | |
| 630 if (!m_Syntax.m_pFileAccess->ReadBlock(buffer, pos, size)) { | |
| 631 break; | 631 break; |
| 632 } | 632 |
| 633 for (FX_DWORD i = 0; i < size; i++) { | 633 for (FX_DWORD i = 0; i < size; i++) { |
| 634 uint8_t byte = buffer[i]; | 634 uint8_t byte = buffer[i]; |
| 635 switch (status) { | 635 switch (status) { |
| 636 case 0: | 636 case 0: |
| 637 if (PDFCharIsWhitespace(byte)) | 637 if (PDFCharIsWhitespace(byte)) |
| 638 status = 1; | 638 status = 1; |
| 639 | 639 |
| 640 if (std::isdigit(byte)) { | 640 if (std::isdigit(byte)) { |
| 641 --i; | 641 --i; |
| 642 status = 1; | 642 status = 1; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 m_Syntax.RestorePos(obj_pos); | 796 m_Syntax.RestorePos(obj_pos); |
| 797 offset = m_Syntax.FindTag("obj", 0); | 797 offset = m_Syntax.FindTag("obj", 0); |
| 798 if (offset == -1) { | 798 if (offset == -1) { |
| 799 offset = 0; | 799 offset = 0; |
| 800 } else { | 800 } else { |
| 801 offset += 3; | 801 offset += 3; |
| 802 } | 802 } |
| 803 FX_FILESIZE nLen = obj_end - obj_pos - offset; | 803 FX_FILESIZE nLen = obj_end - obj_pos - offset; |
| 804 if ((FX_DWORD)nLen > size - i) { | 804 if ((FX_DWORD)nLen > size - i) { |
| 805 pos = obj_end + m_Syntax.m_HeaderOffset; | 805 pos = obj_end + m_Syntax.m_HeaderOffset; |
| 806 bOverFlow = TRUE; | 806 bOverFlow = true; |
| 807 } else { | 807 } else { |
| 808 i += (FX_DWORD)nLen; | 808 i += (FX_DWORD)nLen; |
| 809 } | 809 } |
| 810 if (!m_ObjectInfo.empty() && IsValidObjectNumber(objnum) && | 810 if (!m_ObjectInfo.empty() && IsValidObjectNumber(objnum) && |
| 811 m_ObjectInfo[objnum].pos) { | 811 m_ObjectInfo[objnum].pos) { |
| 812 if (pObject) { | 812 if (pObject) { |
| 813 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); | 813 FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); |
| 814 m_ObjectInfo[objnum].pos = obj_pos; | 814 m_ObjectInfo[objnum].pos = obj_pos; |
| 815 m_ObjVersion.SetAt(objnum, (int16_t)gennum); | 815 m_ObjVersion.SetAt(objnum, (int16_t)gennum); |
| 816 if (oldgen != gennum) { | 816 if (oldgen != gennum) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 953 } else if (byte == "endobj"[inside_index]) { | 953 } else if (byte == "endobj"[inside_index]) { |
| 954 inside_index++; | 954 inside_index++; |
| 955 } | 955 } |
| 956 break; | 956 break; |
| 957 } | 957 } |
| 958 if (bOverFlow) { | 958 if (bOverFlow) { |
| 959 size = 0; | 959 size = 0; |
| 960 break; | 960 break; |
| 961 } | 961 } |
| 962 } | 962 } |
| 963 if (size == 0) | |
| 964 break; | |
|
Wei Li
2015/12/30 20:32:39
I think bOverFlow means overflow to the next buffe
Lei Zhang
2016/01/05 06:08:39
Right. This patch set causes test failures. See pa
| |
| 965 | |
| 963 pos += size; | 966 pos += size; |
| 964 } | 967 } |
| 965 if (last_xref != -1 && last_xref > last_obj) { | 968 if (last_xref != -1 && last_xref > last_obj) { |
| 966 last_trailer = last_xref; | 969 last_trailer = last_xref; |
| 967 } else if (last_trailer == -1 || last_xref < last_obj) { | 970 } else if (last_trailer == -1 || last_xref < last_obj) { |
| 968 last_trailer = m_Syntax.m_FileLen; | 971 last_trailer = m_Syntax.m_FileLen; |
| 969 } | 972 } |
| 970 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; | 973 FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; |
| 971 void* pResult = | 974 void* pResult = |
| 972 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), | 975 FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), |
| 973 sizeof(FX_FILESIZE), CompareFileSize); | 976 sizeof(FX_FILESIZE), CompareFileSize); |
| 974 if (!pResult) { | 977 if (!pResult) { |
| 975 m_SortedOffset.Add(offset); | 978 m_SortedOffset.Add(offset); |
| 976 } | 979 } |
| 977 FX_Free(buffer); | |
| 978 return m_pTrailer && !m_ObjectInfo.empty(); | 980 return m_pTrailer && !m_ObjectInfo.empty(); |
| 979 } | 981 } |
| 980 | 982 |
| 981 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { | 983 FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { |
| 982 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, *pos, 0, nullptr); | 984 CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, *pos, 0, nullptr); |
| 983 if (!pObject) | 985 if (!pObject) |
| 984 return FALSE; | 986 return FALSE; |
| 985 if (m_pDocument) { | 987 if (m_pDocument) { |
| 986 FX_BOOL bInserted = FALSE; | 988 FX_BOOL bInserted = FALSE; |
| 987 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); | 989 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); |
| (...skipping 3997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4985 if (!m_pLinearizedDict) | 4987 if (!m_pLinearizedDict) |
| 4986 return -1; | 4988 return -1; |
| 4987 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); | 4989 CPDF_Array* pRange = m_pLinearizedDict->GetArray("H"); |
| 4988 if (!pRange) | 4990 if (!pRange) |
| 4989 return -1; | 4991 return -1; |
| 4990 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | 4992 CPDF_Object* pStreamLen = pRange->GetElementValue(1); |
| 4991 if (!pStreamLen) | 4993 if (!pStreamLen) |
| 4992 return -1; | 4994 return -1; |
| 4993 return pStreamLen->GetInteger(); | 4995 return pStreamLen->GetInteger(); |
| 4994 } | 4996 } |
| OLD | NEW |