From 12a9940905825e028bebc0bf8d3eddcc65b1933d Mon Sep 17 00:00:00 2001 From: Jun Fang Date: Wed, 10 Sep 2014 16:11:45 -0700 Subject: Check object type for objects used in the dictory of 'Index' BUG=387970 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/551503003 --- .../src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp | 69 +++++++++++++--------- 1 file changed, 40 insertions(+), 29 deletions(-) (limited to 'core/src/fpdfapi/fpdf_parser') diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp index 1b62b06749..97e0d6f5e3 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 +#include +#include + #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 > 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 (startnum); + FX_DWORD count = base::checked_cast (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 (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]); } -- cgit v1.2.3