Chromium Code Reviews

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

Issue 322333002: Fix the potential integer overflow from "offset + size" (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: some formats in the fix of offest+size Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « no previous file | core/src/fxcrt/extension.h » ('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 "../../../include/fpdfapi/fpdf_parser.h" 7 #include "../../../include/fpdfapi/fpdf_parser.h"
8 #include "../../../include/fpdfapi/fpdf_module.h" 8 #include "../../../include/fpdfapi/fpdf_module.h"
9 #include "../../../include/fpdfapi/fpdf_page.h" 9 #include "../../../include/fpdfapi/fpdf_page.h"
10 #include "../../../../third_party/numerics/safe_math.h" 10 #include "../../../../third_party/numerics/safe_math.h"
(...skipping 2851 matching lines...)
2862 break; 2862 break;
2863 case PDFOBJ_REFERENCE: { 2863 case PDFOBJ_REFERENCE: {
2864 CPDF_Reference *pRef = (CPDF_Reference*)pObj; 2864 CPDF_Reference *pRef = (CPDF_Reference*)pObj;
2865 FX_DWORD dwNum = pRef->GetRefObjNum(); 2865 FX_DWORD dwNum = pRef->GetRefObjNum();
2866 FX_FILESIZE offset; 2866 FX_FILESIZE offset;
2867 FX_DWORD original_size = GetObjectSize(dwNum, offset); 2867 FX_DWORD original_size = GetObjectSize(dwNum, offset);
2868 base::CheckedNumeric<FX_DWORD> size = original_size; 2868 base::CheckedNumeric<FX_DWORD> size = original_size;
2869 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m _dwFileLen) { 2869 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m _dwFileLen) {
2870 break; 2870 break;
2871 } 2871 }
2872 2872
2873 size += offset; 2873 size += offset;
2874 size += 512; 2874 size += 512;
2875 if (!size.IsValid()) { 2875 if (!size.IsValid()) {
2876 break; 2876 break;
2877 } 2877 }
2878 if (size.ValueOrDie() > m_dwFileLen) { 2878 if (size.ValueOrDie() > m_dwFileLen) {
2879 size = m_dwFileLen - offset; 2879 size = m_dwFileLen - offset;
2880 } else { 2880 } else {
2881 size = original_size + 512; 2881 size = original_size + 512;
2882 } 2882 }
(...skipping 184 matching lines...)
3067 } 3067 }
3068 FXSYS_qsort(m_parser.m_SortedOffset.GetData(), m_parser.m_SortedOffset.GetSi ze(), sizeof(FX_FILESIZE), _CompareFileSize); 3068 FXSYS_qsort(m_parser.m_SortedOffset.GetData(), m_parser.m_SortedOffset.GetSi ze(), sizeof(FX_FILESIZE), _CompareFileSize);
3069 m_dwRootObjNum = m_parser.GetRootObjNum(); 3069 m_dwRootObjNum = m_parser.GetRootObjNum();
3070 m_dwInfoObjNum = m_parser.GetInfoObjNum(); 3070 m_dwInfoObjNum = m_parser.GetInfoObjNum();
3071 m_pCurrentParser = &m_parser; 3071 m_pCurrentParser = &m_parser;
3072 m_docStatus = PDF_DATAAVAIL_ROOT; 3072 m_docStatus = PDF_DATAAVAIL_ROOT;
3073 return TRUE; 3073 return TRUE;
3074 } 3074 }
3075 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, IFX_DownloadHints* pHint s, FX_BOOL *pExistInFile) 3075 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, IFX_DownloadHints* pHint s, FX_BOOL *pExistInFile)
3076 { 3076 {
3077 CPDF_Object *pRet = NULL; 3077 CPDF_Object *pRet = NULL;
3078 if (pExistInFile) { 3078 FX_DWORD original_size = 0;
3079 FX_FILESIZE offset = 0;
3080 CPDF_Parser *pParser = NULL;
3081
3082 if (pExistInFile) {
3079 *pExistInFile = TRUE; 3083 *pExistInFile = TRUE;
3080 } 3084 }
3085
3081 if (m_pDocument == NULL) { 3086 if (m_pDocument == NULL) {
3082 FX_FILESIZE offset = m_parser.GetObjectOffset(objnum); 3087 original_size = (FX_DWORD)m_parser.GetObjectSize(objnum);
3083 if (offset < 0) { 3088 offset = m_parser.GetObjectOffset(objnum);
3084 *pExistInFile = FALSE; 3089 pParser = &m_parser;
3085 return NULL; 3090 } else {
3086 } 3091 original_size = GetObjectSize(objnum, offset);
3087 FX_DWORD size = (FX_DWORD)m_parser.GetObjectSize(objnum); 3092 pParser = (CPDF_Parser *)(m_pDocument->GetParser());
3088 size = (FX_DWORD)(((FX_FILESIZE)(offset + size + 512)) > m_dwFileLen ? m _dwFileLen - offset : size + 512);
3089 if (!m_pFileAvail->IsDataAvail(offset, size)) {
3090 pHints->AddSegment(offset, size);
3091 return NULL;
3092 }
3093 pRet = m_parser.ParseIndirectObject(NULL, objnum);
3094 if (!pRet && pExistInFile) {
3095 *pExistInFile = FALSE;
3096 }
3097 return pRet;
3098 } 3093 }
3099 FX_FILESIZE offset = 0; 3094
3100 FX_DWORD size = GetObjectSize(objnum, offset); 3095 base::CheckedNumeric<FX_DWORD> size = original_size;
3101 size = (FX_DWORD)((FX_FILESIZE)(offset + size + 512) > m_dwFileLen ? m_dwFil eLen - offset : size + 512); 3096 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) {
3102 if (!m_pFileAvail->IsDataAvail(offset, size)) { 3097 if (pExistInFile)
3103 pHints->AddSegment(offset, size); 3098 *pExistInFile = FALSE;
3099
3104 return NULL; 3100 return NULL;
3105 } 3101 }
3106 CPDF_Parser *pParser = (CPDF_Parser *)(m_pDocument->GetParser()); 3102
3107 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); 3103 size += offset;
3104 size += 512;
3105 if (!size.IsValid()) {
3106 return NULL;
3107 }
3108
3109 if (size.ValueOrDie() > m_dwFileLen) {
3110 size = m_dwFileLen - offset;
3111 } else {
3112 size = original_size + 512;
3113 }
3114
3115 if (!size.IsValid()) {
3116 return NULL;
3117 }
3118
3119 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) {
3120 pHints->AddSegment(offset, size.ValueOrDie());
3121 return NULL;
3122 }
3123
3124 if (pParser) {
3125 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL);
3126 }
3127
3108 if (!pRet && pExistInFile) { 3128 if (!pRet && pExistInFile) {
3109 *pExistInFile = FALSE; 3129 *pExistInFile = FALSE;
3110 } 3130 }
3131
3111 return pRet; 3132 return pRet;
3112 } 3133 }
3134
3113 FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) 3135 FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints)
3114 { 3136 {
3115 FX_BOOL bExist = FALSE; 3137 FX_BOOL bExist = FALSE;
3116 CPDF_Object *pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist); 3138 CPDF_Object *pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist);
3117 if (!bExist) { 3139 if (!bExist) {
3118 if (m_bHaveAcroForm) { 3140 if (m_bHaveAcroForm) {
3119 m_docStatus = PDF_DATAAVAIL_ACROFORM; 3141 m_docStatus = PDF_DATAAVAIL_ACROFORM;
3120 } else { 3142 } else {
3121 m_docStatus = PDF_DATAAVAIL_PAGETREE; 3143 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3122 } 3144 }
(...skipping 1275 matching lines...)
4398 { 4420 {
4399 FX_INT32 iSize = m_childNode.GetSize(); 4421 FX_INT32 iSize = m_childNode.GetSize();
4400 for (FX_INT32 i = 0; i < iSize; ++i) { 4422 for (FX_INT32 i = 0; i < iSize; ++i) {
4401 CPDF_PageNode *pNode = (CPDF_PageNode*)m_childNode[i]; 4423 CPDF_PageNode *pNode = (CPDF_PageNode*)m_childNode[i];
4402 if (pNode) { 4424 if (pNode) {
4403 delete pNode; 4425 delete pNode;
4404 } 4426 }
4405 } 4427 }
4406 m_childNode.RemoveAll(); 4428 m_childNode.RemoveAll();
4407 } 4429 }
OLDNEW
« no previous file with comments | « no previous file | core/src/fxcrt/extension.h » ('j') | no next file with comments »

Powered by Google App Engine