Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Side by Side Diff: core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp

Issue 1543043003: Fix an infinite loop in CPDF_Parser::RebuildCrossRef(). (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698