| Index: core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp | 
| diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp | 
| index 1b62b06749c5d92224e9d484b703b8d985c957eb..97e0d6f5e36a596a660772e5a988518f3bbb2acd 100644 | 
| --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp | 
| +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp | 
| @@ -9,7 +9,9 @@ | 
| #include "../../../include/fpdfapi/fpdf_page.h" | 
| #include "../../../../third_party/numerics/safe_math.h" | 
| #include "../fpdf_page/pageint.h" | 
| -#include <limits.h> | 
| +#include <utility> | 
| +#include <vector> | 
| + | 
| #define _PARSER_OBJECT_LEVLE_		64 | 
| extern const FX_LPCSTR _PDF_CharType; | 
| FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) | 
| @@ -1025,62 +1027,71 @@ FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, FX_FILESIZE& prev, FX_BOOL | 
| } else { | 
| m_Trailers.Add((CPDF_Dictionary*)pStream->GetDict()->Clone()); | 
| } | 
| -    CFX_DWordArray IndexArray, WidthArray; | 
| FX_DWORD nSegs = 0; | 
| +    std::vector <std::pair <FX_INT32, FX_INT32>> arrIndex; | 
| CPDF_Array* pArray = pStream->GetDict()->GetArray(FX_BSTRC("Index")); | 
| -    if (pArray == NULL) { | 
| -        IndexArray.Add(0); | 
| -        IndexArray.Add(size); | 
| -        nSegs = 1; | 
| -    } else { | 
| -        for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { | 
| -            IndexArray.Add(pArray->GetInteger(i)); | 
| +    if (pArray) { | 
| +        FX_DWORD nPairSize = pArray->GetCount() / 2; | 
| +        CPDF_Object* pStartNumObj = NULL; | 
| +        CPDF_Object* pCountObj = NULL; | 
| +        for (FX_DWORD i = 0; i < nPairSize; i++) { | 
| +            pStartNumObj = pArray->GetElement(i * 2); | 
| +            pCountObj = pArray->GetElement(i * 2 + 1); | 
| +            if (pStartNumObj && pStartNumObj->GetType() == PDFOBJ_NUMBER | 
| +                && pCountObj && pCountObj->GetType() == PDFOBJ_NUMBER) { | 
| +                arrIndex.push_back(std::make_pair(pStartNumObj->GetInteger(), pCountObj->GetInteger())); | 
| +            } | 
| +        } | 
| +        nSegs = arrIndex.size(); | 
| +        if (nSegs == 0) { | 
| +            arrIndex.push_back(std::make_pair(0, size)); | 
| +            nSegs = 1; | 
| } | 
| -        nSegs = pArray->GetCount() / 2; | 
| } | 
| pArray = pStream->GetDict()->GetArray(FX_BSTRC("W")); | 
| if (pArray == NULL) { | 
| pStream->Release(); | 
| return FALSE; | 
| } | 
| -    FX_DWORD totalwidth = 0; | 
| -    FX_DWORD i; | 
| -    for (i = 0; i < pArray->GetCount(); i ++) { | 
| +    CFX_DWordArray WidthArray; | 
| +    FX_SAFE_DWORD dwAccWidth = 0; | 
| +    for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { | 
| WidthArray.Add(pArray->GetInteger(i)); | 
| -        if (totalwidth + WidthArray[i] < totalwidth) { | 
| -            pStream->Release(); | 
| -            return FALSE; | 
| -        } | 
| -        totalwidth += WidthArray[i]; | 
| +        dwAccWidth += WidthArray[i]; | 
| } | 
| -    if (totalwidth == 0 || WidthArray.GetSize() < 3) { | 
| +    if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) { | 
| pStream->Release(); | 
| return FALSE; | 
| } | 
| +    FX_DWORD totalWidth = dwAccWidth.ValueOrDie(); | 
| CPDF_StreamAcc acc; | 
| acc.LoadAllData(pStream); | 
| FX_LPCBYTE pData = acc.GetData(); | 
| FX_DWORD dwTotalSize = acc.GetSize(); | 
| FX_DWORD segindex = 0; | 
| -    for (i = 0; i < nSegs; i ++) { | 
| -        FX_INT32 startnum = IndexArray[i * 2]; | 
| +    for (FX_DWORD i = 0; i < nSegs; i ++) { | 
| +        FX_INT32 startnum = arrIndex[i].first; | 
| if (startnum < 0) { | 
| continue; | 
| } | 
| -        m_dwXrefStartObjNum = startnum; | 
| -        FX_DWORD count = IndexArray[i * 2 + 1]; | 
| -        if (segindex + count < segindex || segindex + count == 0 || | 
| -                (FX_DWORD)totalwidth >= UINT_MAX / (segindex + count) || (segindex + count) * (FX_DWORD)totalwidth > dwTotalSize) { | 
| +        m_dwXrefStartObjNum = base::checked_cast<FX_DWORD, FX_INT32> (startnum); | 
| +        FX_DWORD count = base::checked_cast<FX_DWORD, FX_INT32> (arrIndex[i].second); | 
| +        FX_SAFE_DWORD dwCaculatedSize = segindex; | 
| +        dwCaculatedSize += count; | 
| +        dwCaculatedSize *= totalWidth; | 
| +        if (!dwCaculatedSize.IsValid() || dwCaculatedSize.ValueOrDie() > dwTotalSize) { | 
| continue; | 
| } | 
| -        FX_LPCBYTE segstart = pData + segindex * (FX_DWORD)totalwidth; | 
| -        if ((FX_DWORD)startnum + count < (FX_DWORD)startnum || | 
| -                (FX_DWORD)startnum + count > (FX_DWORD)m_V5Type.GetSize()) { | 
| +        FX_LPCBYTE segstart = pData + segindex * totalWidth; | 
| +        FX_SAFE_DWORD dwMaxObjNum = startnum; | 
| +        dwMaxObjNum += count; | 
| +        FX_DWORD dwV5Size = base::checked_cast<FX_DWORD, FX_INT32> (m_V5Type.GetSize()); | 
| +        if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size) { | 
| continue; | 
| } | 
| for (FX_DWORD j = 0; j < count; j ++) { | 
| FX_INT32 type = 1; | 
| -            FX_LPCBYTE entrystart = segstart + j * totalwidth; | 
| +            FX_LPCBYTE entrystart = segstart + j * totalWidth; | 
| if (WidthArray[0]) { | 
| type = _GetVarInt(entrystart, WidthArray[0]); | 
| } | 
|  |