From c655167ed83f78a38264457e65dd11e653ab981d Mon Sep 17 00:00:00 2001 From: Jun Fang Date: Fri, 22 Aug 2014 17:06:32 -0700 Subject: Fix the issue 'SEGV on unknown address in CPDF_DataAvail::GetObjectSize' BUG=387983 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/454283002 --- core/include/fpdfapi/fpdf_parser.h | 230 ++++++++++----------- .../src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp | 41 ++-- 2 files changed, 138 insertions(+), 133 deletions(-) diff --git a/core/include/fpdfapi/fpdf_parser.h b/core/include/fpdfapi/fpdf_parser.h index 7cab2117a2..10072027b3 100644 --- a/core/include/fpdfapi/fpdf_parser.h +++ b/core/include/fpdfapi/fpdf_parser.h @@ -952,198 +952,196 @@ public: CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); ~CPDF_DataAvail(); - virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) FX_OVERRIDE; + virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) FX_OVERRIDE; + virtual void SetDocument(CPDF_Document* pDoc) FX_OVERRIDE; - virtual void SetDocument(CPDF_Document* pDoc) FX_OVERRIDE; + virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) FX_OVERRIDE; + virtual FX_INT32 IsFormAvail(IFX_DownloadHints *pHints) FX_OVERRIDE; - virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) FX_OVERRIDE; + virtual FX_INT32 IsLinearizedPDF() FX_OVERRIDE; - virtual FX_INT32 IsFormAvail(IFX_DownloadHints *pHints) FX_OVERRIDE; - - virtual FX_INT32 IsLinearizedPDF() FX_OVERRIDE; - - virtual FX_BOOL IsLinearized() FX_OVERRIDE + virtual FX_BOOL IsLinearized() FX_OVERRIDE { return m_bLinearized; } - virtual void GetLinearizedMainXRefInfo(FX_FILESIZE *pPos, FX_DWORD *pSize) FX_OVERRIDE; - IFX_FileRead* GetFileRead() const + virtual void GetLinearizedMainXRefInfo(FX_FILESIZE *pPos, FX_DWORD *pSize) FX_OVERRIDE; + IFX_FileRead* GetFileRead() const { return m_pFileRead; } - IFX_FileAvail* GetFileAvail() const + IFX_FileAvail* GetFileAvail() const { return m_pFileAvail; } protected: - FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); - FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePage, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array); - FX_BOOL CheckDocStatus(IFX_DownloadHints *pHints); - FX_BOOL CheckHeader(IFX_DownloadHints* pHints); - FX_BOOL CheckFirstPage(IFX_DownloadHints *pHints); - FX_BOOL CheckEnd(IFX_DownloadHints *pHints); - FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); - FX_BOOL CheckCrossRefItem(IFX_DownloadHints *pHints); - FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); - FX_BOOL CheckRoot(IFX_DownloadHints* pHints); - FX_BOOL CheckInfo(IFX_DownloadHints* pHints); - FX_BOOL CheckPages(IFX_DownloadHints* pHints); - FX_BOOL CheckPage(IFX_DownloadHints* pHints); - FX_BOOL CheckResources(IFX_DownloadHints* pHints); - FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); - FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); - FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); - FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); - FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); - FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints *pHints); + FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); + FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePage, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array); + FX_BOOL CheckDocStatus(IFX_DownloadHints *pHints); + FX_BOOL CheckHeader(IFX_DownloadHints* pHints); + FX_BOOL CheckFirstPage(IFX_DownloadHints *pHints); + FX_BOOL CheckEnd(IFX_DownloadHints *pHints); + FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); + FX_BOOL CheckCrossRefItem(IFX_DownloadHints *pHints); + FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); + FX_BOOL CheckRoot(IFX_DownloadHints* pHints); + FX_BOOL CheckInfo(IFX_DownloadHints* pHints); + FX_BOOL CheckPages(IFX_DownloadHints* pHints); + FX_BOOL CheckPage(IFX_DownloadHints* pHints); + FX_BOOL CheckResources(IFX_DownloadHints* pHints); + FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); + FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); + FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); + FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); + FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); + FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints *pHints); - FX_DWORD CheckCrossRefStream(IFX_DownloadHints *pHints, FX_FILESIZE &xref_offset); - FX_BOOL IsLinearizedFile(FX_LPBYTE pData, FX_DWORD dwLen); - void SetStartOffset(FX_FILESIZE dwOffset); - FX_BOOL GetNextToken(CFX_ByteString &token); - FX_BOOL GetNextChar(FX_BYTE &ch); - CPDF_Object * ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum); - CPDF_Object * GetObject(FX_DWORD objnum, IFX_DownloadHints* pHints, FX_BOOL *pExistInFile); - FX_BOOL GetPageKids(CPDF_Parser *pParser, CPDF_Object *pPages); - FX_BOOL PreparePageItem(); - FX_BOOL LoadPages(IFX_DownloadHints* pHints); - FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); - FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); - FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); - FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); - FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints); + FX_DWORD CheckCrossRefStream(IFX_DownloadHints *pHints, FX_FILESIZE &xref_offset); + FX_BOOL IsLinearizedFile(FX_LPBYTE pData, FX_DWORD dwLen); + void SetStartOffset(FX_FILESIZE dwOffset); + FX_BOOL GetNextToken(CFX_ByteString &token); + FX_BOOL GetNextChar(FX_BYTE &ch); + CPDF_Object * ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum); + CPDF_Object * GetObject(FX_DWORD objnum, IFX_DownloadHints* pHints, FX_BOOL *pExistInFile); + FX_BOOL GetPageKids(CPDF_Parser *pParser, CPDF_Object *pPages); + FX_BOOL PreparePageItem(); + FX_BOOL LoadPages(IFX_DownloadHints* pHints); + FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); + FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); + FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); + FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); + FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints); - FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints); - FX_BOOL HaveResourceAncestor(CPDF_Dictionary *pDict); - FX_BOOL CheckPage(FX_INT32 iPage, IFX_DownloadHints* pHints); - FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); - FX_BOOL LoadDocPage(FX_INT32 iPage, IFX_DownloadHints* pHints); - FX_BOOL CheckPageNode(CPDF_PageNode &pageNodes, FX_INT32 iPage, FX_INT32 &iCount, IFX_DownloadHints* pHints); - FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPageNode, IFX_DownloadHints* pHints); - FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPageNode, IFX_DownloadHints* pHints); - FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); - FX_BOOL IsFirstCheck(int iPage); - void ResetFirstCheck(int iPage); + FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints); + FX_BOOL HaveResourceAncestor(CPDF_Dictionary *pDict); + FX_BOOL CheckPage(FX_INT32 iPage, IFX_DownloadHints* pHints); + FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); + FX_BOOL LoadDocPage(FX_INT32 iPage, IFX_DownloadHints* pHints); + FX_BOOL CheckPageNode(CPDF_PageNode &pageNodes, FX_INT32 iPage, FX_INT32 &iCount, IFX_DownloadHints* pHints); + FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPageNode, IFX_DownloadHints* pHints); + FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPageNode, IFX_DownloadHints* pHints); + FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); + FX_BOOL IsFirstCheck(int iPage); + void ResetFirstCheck(int iPage); - CPDF_Parser m_parser; + CPDF_Parser m_parser; - CPDF_SyntaxParser m_syntaxParser; + CPDF_SyntaxParser m_syntaxParser; - CPDF_Object *m_pRoot; + CPDF_Object *m_pRoot; - FX_DWORD m_dwRootObjNum; + FX_DWORD m_dwRootObjNum; - FX_DWORD m_dwInfoObjNum; + FX_DWORD m_dwInfoObjNum; - CPDF_Object *m_pLinearized; + CPDF_Object *m_pLinearized; - CPDF_Object *m_pTrailer; + CPDF_Object *m_pTrailer; - FX_BOOL m_bDocAvail; + FX_BOOL m_bDocAvail; - FX_FILESIZE m_dwHeaderOffset; + FX_FILESIZE m_dwHeaderOffset; - FX_FILESIZE m_dwLastXRefOffset; + FX_FILESIZE m_dwLastXRefOffset; - FX_FILESIZE m_dwXRefOffset; + FX_FILESIZE m_dwXRefOffset; - FX_FILESIZE m_dwTrailerOffset; + FX_FILESIZE m_dwTrailerOffset; - FX_FILESIZE m_dwCurrentOffset; + FX_FILESIZE m_dwCurrentOffset; - PDF_DATAAVAIL_STATUS m_docStatus; + PDF_DATAAVAIL_STATUS m_docStatus; - IFX_FileAvail* m_pFileAvail; + IFX_FileAvail* m_pFileAvail; - IFX_FileRead* m_pFileRead; + IFX_FileRead* m_pFileRead; - FX_FILESIZE m_dwFileLen; + FX_FILESIZE m_dwFileLen; - CPDF_Document* m_pDocument; + CPDF_Document* m_pDocument; - CPDF_SortObjNumArray m_objnum_array; + CPDF_SortObjNumArray m_objnum_array; - CFX_PtrArray m_objs_array; + CFX_PtrArray m_objs_array; - FX_FILESIZE m_Pos; + FX_FILESIZE m_Pos; - FX_FILESIZE m_bufferOffset; + FX_FILESIZE m_bufferOffset; - FX_DWORD m_bufferSize; + FX_DWORD m_bufferSize; - CFX_ByteString m_WordBuf; + CFX_ByteString m_WordBuf; - FX_BYTE m_WordBuffer[257]; + FX_BYTE m_WordBuffer[257]; - FX_DWORD m_WordSize; + FX_DWORD m_WordSize; - FX_BYTE m_bufferData[512]; + FX_BYTE m_bufferData[512]; - CFX_FileSizeArray m_CrossOffset; + CFX_FileSizeArray m_CrossOffset; - CFX_DWordArray m_XRefStreamList; + CFX_DWordArray m_XRefStreamList; - CFX_DWordArray m_PageObjList; + CFX_DWordArray m_PageObjList; - FX_DWORD m_PagesObjNum; + FX_DWORD m_PagesObjNum; - FX_BOOL m_bLinearized; + FX_BOOL m_bLinearized; - FX_DWORD m_dwFirstPageNo; + FX_DWORD m_dwFirstPageNo; - FX_BOOL m_bLinearedDataOK; + FX_BOOL m_bLinearedDataOK; - FX_BOOL m_bMainXRefLoad; + FX_BOOL m_bMainXRefLoadTried; - FX_BOOL m_bMainXRefLoadedOK; + FX_BOOL m_bMainXRefLoadedOK; - FX_BOOL m_bPagesTreeLoad; + FX_BOOL m_bPagesTreeLoad; - FX_BOOL m_bPagesLoad; + FX_BOOL m_bPagesLoad; - CPDF_Parser * m_pCurrentParser; + CPDF_Parser * m_pCurrentParser; - FX_FILESIZE m_dwCurrentXRefSteam; + FX_FILESIZE m_dwCurrentXRefSteam; - FX_BOOL m_bAnnotsLoad; + FX_BOOL m_bAnnotsLoad; - FX_BOOL m_bHaveAcroForm; + FX_BOOL m_bHaveAcroForm; - FX_DWORD m_dwAcroFormObjNum; + FX_DWORD m_dwAcroFormObjNum; - FX_BOOL m_bAcroFormLoad; + FX_BOOL m_bAcroFormLoad; - CPDF_Object * m_pAcroForm; + CPDF_Object * m_pAcroForm; - CFX_PtrArray m_arrayAcroforms; + CFX_PtrArray m_arrayAcroforms; - CPDF_Dictionary * m_pPageDict; + CPDF_Dictionary * m_pPageDict; - CPDF_Object * m_pPageResource; + CPDF_Object * m_pPageResource; - FX_BOOL m_bNeedDownLoadResource; + FX_BOOL m_bNeedDownLoadResource; - FX_BOOL m_bPageLoadedOK; + FX_BOOL m_bPageLoadedOK; - FX_BOOL m_bLinearizedFormParamLoad; + FX_BOOL m_bLinearizedFormParamLoad; - CFX_PtrArray m_PagesArray; + CFX_PtrArray m_PagesArray; - FX_DWORD m_dwEncryptObjNum; + FX_DWORD m_dwEncryptObjNum; - FX_FILESIZE m_dwPrevXRefOffset; + FX_FILESIZE m_dwPrevXRefOffset; - FX_BOOL m_bTotalLoadPageTree; + FX_BOOL m_bTotalLoadPageTree; - FX_BOOL m_bCurPageDictLoadOK; + FX_BOOL m_bCurPageDictLoadOK; - CPDF_PageNode m_pageNodes; + CPDF_PageNode m_pageNodes; - CFX_CMapDWordToDWord * m_pageMapCheckState; + CFX_CMapDWordToDWord * m_pageMapCheckState; - CFX_CMapDWordToDWord * m_pagesLoadState; + CFX_CMapDWordToDWord * m_pagesLoadState; }; #endif diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp index ce397d2a53..d05dea4470 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp @@ -2729,7 +2729,7 @@ CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRea m_dwPrevXRefOffset = 0; m_dwLastXRefOffset = 0; m_bDocAvail = FALSE; - m_bMainXRefLoad = FALSE; + m_bMainXRefLoadTried = FALSE; m_bDocAvail = FALSE; m_bLinearized = FALSE; m_bPagesLoad = FALSE; @@ -4107,23 +4107,30 @@ FX_BOOL CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints) if (m_bLinearedDataOK) { return TRUE; } - if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset))) { - pHints->AddSegment(m_dwLastXRefOffset, (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset)); - return FALSE; - } - FX_DWORD dwRet = 0; - if (!m_bMainXRefLoad) { - dwRet = ((CPDF_Parser *)m_pDocument->GetParser())->LoadLinearizedMainXRefTable(); - if (dwRet == PDFPARSE_ERROR_SUCCESS) { - if (!PreparePageItem()) { - return FALSE; - } - m_bMainXRefLoadedOK = TRUE; + + if (!m_bMainXRefLoadTried) { + FX_SAFE_DWORD data_size = m_dwFileLen; + data_size -= m_dwLastXRefOffset; + if (!data_size.IsValid()) { + return FALSE; + } + if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, data_size.ValueOrDie())) { + pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie()); + return FALSE; } - m_bMainXRefLoad = TRUE; + FX_DWORD dwRet = ((CPDF_Parser *)m_pDocument->GetParser())->LoadLinearizedMainXRefTable(); + m_bMainXRefLoadTried = TRUE; + if (dwRet != PDFPARSE_ERROR_SUCCESS) { + return FALSE; + } + if (!PreparePageItem()) { + return FALSE; + } + m_bMainXRefLoadedOK = TRUE; + m_bLinearedDataOK = TRUE; } - m_bLinearedDataOK = TRUE; - return TRUE; + + return m_bLinearedDataOK; } FX_BOOL CPDF_DataAvail::CheckPageAnnots(FX_INT32 iPage, IFX_DownloadHints* pHints) { @@ -4351,7 +4358,7 @@ FX_INT32 CPDF_DataAvail::IsFormAvail(IFX_DownloadHints *pHints) if (!pAcroForm) { return PDFFORM_NOTEXIST; } - if (!m_bMainXRefLoad && !CheckLinearizedData(pHints)) { + if (!CheckLinearizedData(pHints)) { return PDFFORM_NOTAVAIL; } if (!m_objs_array.GetSize()) { -- cgit v1.2.3