Fix the typo of "Resources" keyword
[pdfium.git] / core / src / fpdfapi / fpdf_parser / fpdf_parser_parser.cpp
index 3bfd37f..b90c784 100644 (file)
@@ -7,6 +7,7 @@
 #include "../../../include/fpdfapi/fpdf_parser.h"
 #include "../../../include/fpdfapi/fpdf_module.h"
 #include "../../../include/fpdfapi/fpdf_page.h"
+#include "../../../../third_party/numerics/safe_math.h"
 #include "../fpdf_page/pageint.h"
 #include <limits.h>
 #define _PARSER_OBJECT_LEVLE_          64
@@ -635,7 +636,6 @@ FX_BOOL CPDF_Parser::RebuildCrossRef()
         }
         for (FX_DWORD i = 0; i < size; i ++) {
             FX_BYTE byte = buffer[i];
-            FX_LPBYTE pData = buffer + i;
             switch (status) {
                 case 0:
                     if (_PDF_CharType[byte] == 'W') {
@@ -1210,7 +1210,7 @@ CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum)
     if (m_ObjectStreamMap.Lookup((void*)(FX_UINTPTR)objnum, (void*&)pStreamAcc)) {
         return pStreamAcc;
     }
-    const CPDF_Stream* pStream = (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum);
+    const CPDF_Stream* pStream = m_pDocument ? (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum) : NULL;
     if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
         return NULL;
     }
@@ -1269,7 +1269,7 @@ void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, FX_LPBYTE& pBuffer, FX_DWOR
                 if (n == 1) {
                     size = totalsize - (thisoff + offset);
                 } else {
-                    FX_DWORD nextnum = syntax.GetDirectNum();
+                    syntax.GetDirectNum();  // Skip nextnum.
                     FX_DWORD nextoff = syntax.GetDirectNum();
                     size = nextoff - thisoff;
                 }
@@ -1380,7 +1380,6 @@ CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList,
     if (bsWord == FX_BSTRC("endobj")) {
         endOffset = m_Syntax.SavePos();
     }
-    FX_DWORD objSize = endOffset - objOffset;
     m_Syntax.RestorePos(SavedPos);
     if (pObj && !objnum) {
         pObj->m_ObjNum = real_objnum;
@@ -1622,7 +1621,6 @@ FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable()
         m_pTrailer = NULL;
     }
     m_Syntax.RestorePos(m_LastXRefOffset - m_Syntax.m_HeaderOffset);
-    FX_FILESIZE dwSavedPos = m_Syntax.SavePos();
     FX_BYTE ch = 0;
     FX_DWORD dwCount = 0;
     m_Syntax.GetNextChar(ch);
@@ -1649,7 +1647,7 @@ FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable()
         m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;
         return PDFPARSE_ERROR_FORMAT;
     }
-    FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_DWORD), _CompareDWord);
+    FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
     m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;
     return PDFPARSE_ERROR_SUCCESS;
 }
@@ -2046,7 +2044,6 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, FX_DWO
         }
         return NULL;
     }
-    FX_FILESIZE wordOffset = m_Pos - word.GetLength();
     if (bIsNumber) {
         FX_FILESIZE SavedPos = m_Pos;
         CFX_ByteString nextword = GetNextWord(bIsNumber);
@@ -2094,7 +2091,6 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, FX_DWO
         if (bTypeOnly) {
             return (CPDF_Object*)PDFOBJ_STRING;
         }
-        FX_FILESIZE SavedPos = m_Pos - 1;
         CFX_ByteString str = ReadString();
         if (m_pCryptoHandler && bDecrypt) {
             m_pCryptoHandler->Decrypt(objnum, gennum, str);
@@ -2106,7 +2102,6 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, FX_DWO
         if (bTypeOnly) {
             return (CPDF_Object*)PDFOBJ_STRING;
         }
-        FX_FILESIZE SavedPos = m_Pos - 1;
         CFX_ByteString str = ReadHexString();
         if (m_pCryptoHandler && bDecrypt) {
             m_pCryptoHandler->Decrypt(objnum, gennum, str);
@@ -2119,9 +2114,7 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, FX_DWO
             return (CPDF_Object*)PDFOBJ_ARRAY;
         }
         CPDF_Array* pArray = CPDF_Array::Create();
-        FX_FILESIZE firstPos = m_Pos - 1;
         while (1) {
-            FX_FILESIZE SavedPos = m_Pos;
             CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);
             if (pObj == NULL) {
                 return pArray;
@@ -2408,28 +2401,29 @@ CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, PARSE_CONTEXT
         FX_DWORD objnum, FX_DWORD gennum)
 {
     CPDF_Object* pLenObj = pDict->GetElement(FX_BSTRC("Length"));
-    FX_DWORD len = 0;
+    FX_FILESIZE len = 0;
     if (pLenObj && ((pLenObj->GetType() != PDFOBJ_REFERENCE) ||
                     ((((CPDF_Reference*)pLenObj)->GetObjList() != NULL) &&
                      ((CPDF_Reference*)pLenObj)->GetRefObjNum() != objnum))) {
-        FX_FILESIZE pos = m_Pos;
-        if (pLenObj) {
-            len = pLenObj->GetInteger();
-        }
-        m_Pos = pos;
-        if (len > 0x40000000) {
-            return NULL;
-        }
+        len = pLenObj->GetInteger();
     }
+
     ToNextLine();
     FX_FILESIZE StreamStartPos = m_Pos;
     if (pContext) {
         pContext->m_DataStart = m_Pos;
     }
-    m_Pos += len;
+
+    base::CheckedNumeric<FX_FILESIZE> pos = m_Pos;
+    pos += len;
+    if (pos.IsValid() && pos.ValueOrDie() < m_FileLen) {
+        m_Pos = pos.ValueOrDie();
+    } else {
+        return NULL;
+    }
+
     CPDF_CryptoHandler* pCryptoHandler = objnum == (FX_DWORD)m_MetadataObjnum ? NULL : m_pCryptoHandler;
     if (pCryptoHandler == NULL) {
-        FX_FILESIZE SavedPos = m_Pos;
         GetNextWord();
         if (m_WordSize < 9 || FXSYS_memcmp32(m_WordBuffer, "endstream", 9)) {
             m_Pos = StreamStartPos;
@@ -2861,13 +2855,27 @@ FX_BOOL CPDF_DataAvail::IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePa
                     CPDF_Reference *pRef = (CPDF_Reference*)pObj;
                     FX_DWORD dwNum = pRef->GetRefObjNum();
                     FX_FILESIZE offset;
-                    FX_DWORD size = GetObjectSize(pRef->GetRefObjNum(), offset);
-                    if (!size) {
+                    FX_DWORD original_size = GetObjectSize(dwNum, offset);
+                    base::CheckedNumeric<FX_DWORD> size = original_size;
+                    if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) {
                         break;
                     }
-                    size = (FX_DWORD)((FX_FILESIZE)(offset + size + 512) > m_dwFileLen ? m_dwFileLen - offset : size + 512);
-                    if (!m_pFileAvail->IsDataAvail(offset, size)) {
-                        pHints->AddSegment(offset, size);
+                    
+                    size += offset;
+                    size += 512;
+                    if (!size.IsValid()) {
+                        break;
+                    }
+                    if (size.ValueOrDie() > m_dwFileLen) {
+                        size = m_dwFileLen - offset;
+                    } else {
+                        size = original_size + 512;
+                    }
+                    if (!size.IsValid()) {
+                        break;
+                    }
+                    if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) {
+                        pHints->AddSegment(offset, size.ValueOrDie());
                         ret_array.Add(pObj);
                         count++;
                     } else if (!m_objnum_array.Find(dwNum)) {
@@ -3057,42 +3065,64 @@ FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints)
 }
 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, IFX_DownloadHints* pHints, FX_BOOL *pExistInFile)
 {
-    CPDF_Object *pRet = NULL;
-    if (pExistInFile) {
+    CPDF_Object *pRet         = NULL;
+    FX_DWORD    original_size = 0;
+    FX_FILESIZE offset        = 0;
+    CPDF_Parser *pParser      = NULL;
+
+    if (pExistInFile) { 
         *pExistInFile = TRUE;
     }
+
     if (m_pDocument == NULL) {
-        FX_FILESIZE offset = m_parser.GetObjectOffset(objnum);
-        if (offset < 0) {
-            *pExistInFile = FALSE;
-            return NULL;
-        }
-        FX_DWORD size = (FX_DWORD)m_parser.GetObjectSize(objnum);
-        size = (FX_DWORD)(((FX_FILESIZE)(offset + size + 512)) > m_dwFileLen ? m_dwFileLen - offset : size + 512);
-        if (!m_pFileAvail->IsDataAvail(offset, size)) {
-            pHints->AddSegment(offset, size);
-            return NULL;
-        }
-        pRet = m_parser.ParseIndirectObject(NULL, objnum);
-        if (!pRet && pExistInFile) {
-            *pExistInFile = FALSE;
-        }
-        return pRet;
+        original_size = (FX_DWORD)m_parser.GetObjectSize(objnum);
+        offset        = m_parser.GetObjectOffset(objnum);
+        pParser       = &m_parser; 
+    } else {
+        original_size = GetObjectSize(objnum, offset);
+        pParser       = (CPDF_Parser *)(m_pDocument->GetParser());
     }
-    FX_FILESIZE offset = 0;
-    FX_DWORD size = GetObjectSize(objnum, offset);
-    size = (FX_DWORD)((FX_FILESIZE)(offset + size + 512) > m_dwFileLen ? m_dwFileLen - offset : size + 512);
-    if (!m_pFileAvail->IsDataAvail(offset, size)) {
-        pHints->AddSegment(offset, size);
+
+    base::CheckedNumeric<FX_DWORD> size = original_size;
+    if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) {
+        if (pExistInFile)
+           *pExistInFile = FALSE;
+
         return NULL;
     }
-    CPDF_Parser *pParser = (CPDF_Parser *)(m_pDocument->GetParser());
-    pRet = pParser->ParseIndirectObject(NULL, objnum, NULL);
+    size += offset;
+    size += 512;
+    if (!size.IsValid()) {
+        return NULL;
+    }
+
+    if (size.ValueOrDie() > m_dwFileLen) {
+        size = m_dwFileLen - offset;
+    } else {
+        size = original_size + 512;
+    }
+
+    if (!size.IsValid()) {
+        return NULL;
+    }
+
+    if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) {
+        pHints->AddSegment(offset, size.ValueOrDie());
+        return NULL;
+    }
+
+    if (pParser) {
+        pRet = pParser->ParseIndirectObject(NULL, objnum, NULL);
+    }
+
     if (!pRet && pExistInFile) {
         *pExistInFile = FALSE;
     }
     return pRet;
 }
+
 FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints)
 {
     FX_BOOL bExist = FALSE;
@@ -3318,7 +3348,6 @@ FX_BOOL CPDF_DataAvail::CheckPages(IFX_DownloadHints* pHints)
         }
         return FALSE;
     }
-    FX_BOOL bNeedLoad = FALSE;
     if (!GetPageKids(m_pCurrentParser, pPages)) {
         pPages->Release();
         m_docStatus = PDF_DATAAVAIL_ERROR;
@@ -3352,7 +3381,6 @@ FX_BOOL CPDF_DataAvail::CheckHeader(IFX_DownloadHints* pHints)
 }
 FX_BOOL CPDF_DataAvail::CheckFirstPage(IFX_DownloadHints *pHints)
 {
-    FX_DWORD dwFirstPageEndOffset = 0;
     CPDF_Dictionary* pDict = m_pLinearized->GetDict();
     CPDF_Object *pEndOffSet = pDict ? pDict->GetElement(FX_BSTRC("E")) : NULL;
     if (!pEndOffSet) {
@@ -3469,7 +3497,6 @@ FX_BOOL CPDF_DataAvail::IsLinearizedFile(FX_LPBYTE pData, FX_DWORD dwLen)
     m_syntaxParser.InitParser((IFX_FileStream*)file, offset);
     m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9);
     FX_BOOL bNumber = FALSE;
-    FX_FILESIZE dwSavePos = m_syntaxParser.SavePos();
     CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber);
     if (!bNumber) {
         return FALSE;
@@ -3547,7 +3574,6 @@ FX_DWORD CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, FX_FILES
         CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE));
         m_parser.m_Syntax.InitParser((IFX_FileStream*)file, 0);
         FX_BOOL bNumber = FALSE;
-        FX_FILESIZE dwSavePos = m_parser.m_Syntax.SavePos();
         CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber);
         if (!bNumber) {
             return -1;
@@ -3729,7 +3755,6 @@ FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(IFX_DownloadHints *pHints)
 }
 FX_BOOL CPDF_DataAvail::CheckCrossRef(IFX_DownloadHints* pHints)
 {
-    FX_FILESIZE dwSavePos = m_Pos;
     FX_INT32 iSize = 0;
     CFX_ByteString token;
     if (!GetNextToken(token)) {
@@ -4156,7 +4181,7 @@ FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary *pDict)
     if (!pParentDict) {
         return FALSE;
     }
-    CPDF_Object *pRet = pParentDict->GetElement("Resource");
+    CPDF_Object *pRet = pParentDict->GetElement("Resources");
     if (pRet) {
         m_pPageResource = pRet;
         return TRUE;
@@ -4262,11 +4287,12 @@ FX_BOOL CPDF_DataAvail::IsPageAvail(FX_INT32 iPage, IFX_DownloadHints* pHints)
         }
     }
     if (m_pPageDict && !m_bNeedDownLoadResource) {
-        CPDF_Object *pRes = m_pPageDict->GetElement("Resource");
-        if (!pRes) {
+        m_pPageResource = m_pPageDict->GetElement("Resources");
+        if (!m_pPageResource) {
             m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict);
+        } else {
+            m_bNeedDownLoadResource = TRUE;
         }
-        m_bNeedDownLoadResource = FALSE;
     }
     if (m_bNeedDownLoadResource) {
         FX_BOOL bRet = CheckResources(pHints);
@@ -4364,7 +4390,6 @@ FX_BOOL CPDF_SortObjNumArray::BinarySearch(FX_DWORD value, FX_INT32 &iNext)
     FX_INT32 iMid = 0;
     while (iLow <= iHigh) {
         iMid = (iLow + iHigh) / 2;
-        FX_DWORD tt = m_number_array.GetAt(iMid);
         if (m_number_array.GetAt(iMid) == value) {
             iNext = iMid;
             return TRUE;