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

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: rebase Created 4 years, 11 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 | core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp » ('j') | 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 <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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698