diff options
Diffstat (limited to 'core')
41 files changed, 1190 insertions, 1123 deletions
diff --git a/core/include/fpdfapi/cfdf_document.h b/core/include/fpdfapi/cfdf_document.h new file mode 100644 index 0000000000..6fb8ab7ba2 --- /dev/null +++ b/core/include/fpdfapi/cfdf_document.h @@ -0,0 +1,36 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_INCLUDE_FPDFAPI_CFDF_DOCUMENT_H_ +#define CORE_INCLUDE_FPDFAPI_CFDF_DOCUMENT_H_ + +#include "core/include/fpdfapi/fpdf_objects.h" +#include "core/include/fxcrt/fx_stream.h" +#include "core/include/fxcrt/fx_system.h" + +class CPDF_Dictionary; + +class CFDF_Document : public CPDF_IndirectObjectHolder { + public: + static CFDF_Document* CreateNewDoc(); + static CFDF_Document* ParseFile(IFX_FileRead* pFile, + FX_BOOL bOwnFile = FALSE); + static CFDF_Document* ParseMemory(const uint8_t* pData, FX_DWORD size); + ~CFDF_Document(); + + FX_BOOL WriteBuf(CFX_ByteTextBuf& buf) const; + CPDF_Dictionary* GetRoot() const { return m_pRootDict; } + + protected: + CFDF_Document(); + void ParseStream(IFX_FileRead* pFile, FX_BOOL bOwnFile); + + CPDF_Dictionary* m_pRootDict; + IFX_FileRead* m_pFile; + FX_BOOL m_bOwnFile; +}; + +#endif // CORE_INCLUDE_FPDFAPI_CFDF_DOCUMENT_H_ diff --git a/core/include/fpdfapi/cpdf_document.h b/core/include/fpdfapi/cpdf_document.h index bba89c822c..c759861cd7 100644 --- a/core/include/fpdfapi/cpdf_document.h +++ b/core/include/fpdfapi/cpdf_document.h @@ -20,6 +20,16 @@ class CPDF_IccProfile; class CPDF_Image; class CPDF_Pattern; +#define FPDFPERM_PRINT 0x0004 +#define FPDFPERM_MODIFY 0x0008 +#define FPDFPERM_EXTRACT 0x0010 +#define FPDFPERM_ANNOT_FORM 0x0020 +#define FPDFPERM_FILL_FORM 0x0100 +#define FPDFPERM_EXTRACT_ACCESS 0x0200 +#define FPDFPERM_ASSEMBLE 0x0400 +#define FPDFPERM_PRINT_HIGH 0x0800 +#define FPDF_PAGE_MAX_NUM 0xFFFFF + class CPDF_Document : public CFX_PrivateData, public CPDF_IndirectObjectHolder { public: CPDF_Document(); diff --git a/core/include/fpdfapi/fpdf_objects.h b/core/include/fpdfapi/fpdf_objects.h index a6fa056e13..42282a1dcc 100644 --- a/core/include/fpdfapi/fpdf_objects.h +++ b/core/include/fpdfapi/fpdf_objects.h @@ -333,6 +333,7 @@ class CPDF_Dictionary : public CPDF_Object { } FX_BOOL KeyExist(const CFX_ByteStringC& key) const; + bool IsSignatureDict() const; // Set* functions invalidate iterators for the element with the key |key|. void SetAt(const CFX_ByteStringC& key, CPDF_Object* pObj); diff --git a/core/include/fpdfapi/fpdf_page.h b/core/include/fpdfapi/fpdf_page.h index 7c27340525..534faf2c2b 100644 --- a/core/include/fpdfapi/fpdf_page.h +++ b/core/include/fpdfapi/fpdf_page.h @@ -10,7 +10,6 @@ #include <deque> #include <memory> -#include "core/include/fpdfapi/fpdf_parser.h" #include "core/include/fpdfapi/fpdf_resource.h" #include "core/include/fxge/fx_dib.h" diff --git a/core/include/fpdfapi/fpdf_parser.h b/core/include/fpdfapi/fpdf_parser.h deleted file mode 100644 index 9504061fcf..0000000000 --- a/core/include/fpdfapi/fpdf_parser.h +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_INCLUDE_FPDFAPI_FPDF_PARSER_H_ -#define CORE_INCLUDE_FPDFAPI_FPDF_PARSER_H_ - -#include <map> -#include <memory> -#include <set> - -#include "core/include/fpdfapi/fpdf_objects.h" -#include "core/include/fxcrt/fx_basic.h" - -class CFX_Font; -class CFX_Matrix; -class CPDF_ColorSpace; -class IPDF_CryptoHandler; -class CPDF_Document; -class CPDF_DocPageData; -class CPDF_DocRenderData; -class CPDF_Font; -class CPDF_FontEncoding; -class CPDF_IccProfile; -class CPDF_Image; -class CPDF_Object; -class CPDF_Parser; -class CPDF_Pattern; -class CPDF_StandardSecurityHandler; -class CPDF_SyntaxParser; -class IPDF_SecurityHandler; - -#define FPDFPERM_PRINT 0x0004 -#define FPDFPERM_MODIFY 0x0008 -#define FPDFPERM_EXTRACT 0x0010 -#define FPDFPERM_ANNOT_FORM 0x0020 -#define FPDFPERM_FILL_FORM 0x0100 -#define FPDFPERM_EXTRACT_ACCESS 0x0200 -#define FPDFPERM_ASSEMBLE 0x0400 -#define FPDFPERM_PRINT_HIGH 0x0800 -#define FPDF_PAGE_MAX_NUM 0xFFFFF - -// Indexed by 8-bit char code, contains unicode code points. -extern const FX_WORD PDFDocEncoding[256]; - - -CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& orig); -CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig); -CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig); -CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, - FX_BOOL bHex = FALSE); -CFX_WideString PDF_DecodeText(const uint8_t* pData, FX_DWORD size); -CFX_WideString PDF_DecodeText(const CFX_ByteString& bstr); -CFX_ByteString PDF_EncodeText(const FX_WCHAR* pString, int len = -1); -CFX_ByteString PDF_EncodeText(const CFX_WideString& str); - -class CFDF_Document : public CPDF_IndirectObjectHolder { - public: - static CFDF_Document* CreateNewDoc(); - static CFDF_Document* ParseFile(IFX_FileRead* pFile, - FX_BOOL bOwnFile = FALSE); - static CFDF_Document* ParseMemory(const uint8_t* pData, FX_DWORD size); - ~CFDF_Document(); - - FX_BOOL WriteBuf(CFX_ByteTextBuf& buf) const; - CPDF_Dictionary* GetRoot() const { return m_pRootDict; } - - protected: - CFDF_Document(); - void ParseStream(IFX_FileRead* pFile, FX_BOOL bOwnFile); - - CPDF_Dictionary* m_pRootDict; - IFX_FileRead* m_pFile; - FX_BOOL m_bOwnFile; -}; - -void FlateEncode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size); -void FlateEncode(const uint8_t* src_buf, - FX_DWORD src_size, - int predictor, - int Colors, - int BitsPerComponent, - int Columns, - uint8_t*& dest_buf, - FX_DWORD& dest_size); -FX_DWORD FlateDecode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size); -FX_DWORD RunLengthDecode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size); -bool IsSignatureDict(const CPDF_Dictionary* pDict); - -class IFX_FileAvail { - public: - virtual ~IFX_FileAvail() {} - virtual FX_BOOL IsDataAvail(FX_FILESIZE offset, FX_DWORD size) = 0; -}; -class IFX_DownloadHints { - public: - virtual ~IFX_DownloadHints() {} - virtual void AddSegment(FX_FILESIZE offset, FX_DWORD size) = 0; -}; - -class IPDF_DataAvail { - public: - // Must match PDF_DATA_* definitions in public/fpdf_dataavail.h, but cannot - // #include that header. fpdfsdk/src/fpdf_dataavail.cpp has static_asserts - // to make sure the two sets of values match. - enum DocAvailStatus { - DataError = -1, // PDF_DATA_ERROR - DataNotAvailable = 0, // PDF_DATA_NOTAVAIL - DataAvailable = 1, // PDF_DATA_AVAIL - }; - - // Must match PDF_*LINEAR* definitions in public/fpdf_dataavail.h, but cannot - // #include that header. fpdfsdk/src/fpdf_dataavail.cpp has static_asserts - // to make sure the two sets of values match. - enum DocLinearizationStatus { - LinearizationUnknown = -1, // PDF_LINEARIZATION_UNKNOWN - NotLinearized = 0, // PDF_NOT_LINEARIZED - Linearized = 1, // PDF_LINEARIZED - }; - - // Must match PDF_FORM_* definitions in public/fpdf_dataavail.h, but cannot - // #include that header. fpdfsdk/src/fpdf_dataavail.cpp has static_asserts - // to make sure the two sets of values match. - enum DocFormStatus { - FormError = -1, // PDF_FORM_ERROR - FormNotAvailable = 0, // PDF_FORM_NOTAVAIL - FormAvailable = 1, // PDF_FORM_AVAIL - FormNotExist = 2, // PDF_FORM_NOTEXIST - }; - - static IPDF_DataAvail* Create(IFX_FileAvail* pFileAvail, - IFX_FileRead* pFileRead); - virtual ~IPDF_DataAvail() {} - - IFX_FileAvail* GetFileAvail() const { return m_pFileAvail; } - IFX_FileRead* GetFileRead() const { return m_pFileRead; } - - virtual DocAvailStatus IsDocAvail(IFX_DownloadHints* pHints) = 0; - virtual void SetDocument(CPDF_Document* pDoc) = 0; - virtual DocAvailStatus IsPageAvail(int iPage, IFX_DownloadHints* pHints) = 0; - virtual FX_BOOL IsLinearized() = 0; - virtual DocFormStatus IsFormAvail(IFX_DownloadHints* pHints) = 0; - virtual DocLinearizationStatus IsLinearizedPDF() = 0; - virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, - FX_DWORD* pSize) = 0; - - protected: - IPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); - - IFX_FileAvail* m_pFileAvail; - IFX_FileRead* m_pFileRead; -}; - -enum PDF_PAGENODE_TYPE { - PDF_PAGENODE_UNKNOWN = 0, - PDF_PAGENODE_PAGE, - PDF_PAGENODE_PAGES, - PDF_PAGENODE_ARRAY, -}; - -class CPDF_PageNode { - public: - CPDF_PageNode(); - ~CPDF_PageNode(); - - PDF_PAGENODE_TYPE m_type; - FX_DWORD m_dwPageNo; - CFX_ArrayTemplate<CPDF_PageNode*> m_childNode; -}; - -enum PDF_DATAAVAIL_STATUS { - PDF_DATAAVAIL_HEADER = 0, - PDF_DATAAVAIL_FIRSTPAGE, - PDF_DATAAVAIL_FIRSTPAGE_PREPARE, - PDF_DATAAVAIL_HINTTABLE, - PDF_DATAAVAIL_END, - PDF_DATAAVAIL_CROSSREF, - PDF_DATAAVAIL_CROSSREF_ITEM, - PDF_DATAAVAIL_CROSSREF_STREAM, - PDF_DATAAVAIL_TRAILER, - PDF_DATAAVAIL_LOADALLCROSSREF, - PDF_DATAAVAIL_ROOT, - PDF_DATAAVAIL_INFO, - PDF_DATAAVAIL_ACROFORM, - PDF_DATAAVAIL_ACROFORM_SUBOBJECT, - PDF_DATAAVAIL_PAGETREE, - PDF_DATAAVAIL_PAGE, - PDF_DATAAVAIL_PAGE_LATERLOAD, - PDF_DATAAVAIL_RESOURCES, - PDF_DATAAVAIL_DONE, - PDF_DATAAVAIL_ERROR, - PDF_DATAAVAIL_LOADALLFILE, - PDF_DATAAVAIL_TRAILER_APPEND -}; - -// Public for testing. -FX_DWORD A85Decode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size); -// Public for testing. -FX_DWORD HexDecode(const uint8_t* src_buf, - FX_DWORD src_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size); -// Public for testing. -FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, - const uint8_t* src_buf, - FX_DWORD src_size, - CPDF_Dictionary* pParams, - FX_DWORD estimated_size, - uint8_t*& dest_buf, - FX_DWORD& dest_size); -FX_BOOL PDF_DataDecode(const uint8_t* src_buf, - FX_DWORD src_size, - const CPDF_Dictionary* pDict, - uint8_t*& dest_buf, - FX_DWORD& dest_size, - CFX_ByteString& ImageEncoding, - CPDF_Dictionary*& pImageParms, - FX_DWORD estimated_size, - FX_BOOL bImageAcc); - -#endif // CORE_INCLUDE_FPDFAPI_FPDF_PARSER_H_ diff --git a/core/include/fpdfapi/fpdf_parser_decode.h b/core/include/fpdfapi/fpdf_parser_decode.h new file mode 100644 index 0000000000..1217c7ea21 --- /dev/null +++ b/core/include/fpdfapi/fpdf_parser_decode.h @@ -0,0 +1,76 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_INCLUDE_FPDFAPI_FPDF_PARSER_DECODE_H_ +#define CORE_INCLUDE_FPDFAPI_FPDF_PARSER_DECODE_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CPDF_Dictionary; + +// Indexed by 8-bit char code, contains unicode code points. +extern const FX_WORD PDFDocEncoding[256]; + +CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& orig); +CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig); +CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig); +CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, + FX_BOOL bHex = FALSE); +CFX_WideString PDF_DecodeText(const uint8_t* pData, FX_DWORD size); +CFX_WideString PDF_DecodeText(const CFX_ByteString& bstr); +CFX_ByteString PDF_EncodeText(const FX_WCHAR* pString, int len = -1); +CFX_ByteString PDF_EncodeText(const CFX_WideString& str); + +void FlateEncode(const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size); +void FlateEncode(const uint8_t* src_buf, + FX_DWORD src_size, + int predictor, + int Colors, + int BitsPerComponent, + int Columns, + uint8_t*& dest_buf, + FX_DWORD& dest_size); +FX_DWORD FlateDecode(const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size); +FX_DWORD RunLengthDecode(const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size); + +// Public for testing. +FX_DWORD A85Decode(const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size); +// Public for testing. +FX_DWORD HexDecode(const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size); +// Public for testing. +FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, + const uint8_t* src_buf, + FX_DWORD src_size, + CPDF_Dictionary* pParams, + FX_DWORD estimated_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size); +FX_BOOL PDF_DataDecode(const uint8_t* src_buf, + FX_DWORD src_size, + const CPDF_Dictionary* pDict, + uint8_t*& dest_buf, + FX_DWORD& dest_size, + CFX_ByteString& ImageEncoding, + CPDF_Dictionary*& pImageParms, + FX_DWORD estimated_size, + FX_BOOL bImageAcc); + +#endif // CORE_INCLUDE_FPDFAPI_FPDF_PARSER_DECODE_H_ diff --git a/core/include/fpdfapi/fpdf_resource.h b/core/include/fpdfapi/fpdf_resource.h index 6bae2ac469..a5acc77762 100644 --- a/core/include/fpdfapi/fpdf_resource.h +++ b/core/include/fpdfapi/fpdf_resource.h @@ -9,7 +9,7 @@ #include <map> -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/fpdf_objects.h" #include "core/include/fxcrt/fx_system.h" #include "core/include/fxge/fx_font.h" @@ -22,6 +22,7 @@ class CPDF_CIDFont; class CPDF_CMap; class CPDF_Color; class CPDF_ColorSpace; +class CPDF_Document; class CPDF_FontEncoding; class CPDF_Form; class CPDF_Function; diff --git a/core/include/fpdfapi/fpdf_serial.h b/core/include/fpdfapi/fpdf_serial.h index 6ed3756803..8cf3fb8a1e 100644 --- a/core/include/fpdfapi/fpdf_serial.h +++ b/core/include/fpdfapi/fpdf_serial.h @@ -11,6 +11,7 @@ #include "core/include/fpdfapi/fpdf_pageobj.h" class CPDF_XRefStream; +class IPDF_CryptoHandler; CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj); diff --git a/core/include/fpdfapi/ipdf_data_avail.h b/core/include/fpdfapi/ipdf_data_avail.h new file mode 100644 index 0000000000..5b8fd0b5e2 --- /dev/null +++ b/core/include/fpdfapi/ipdf_data_avail.h @@ -0,0 +1,80 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_INCLUDE_FPDFAPI_IPDF_DATA_AVAIL_H_ +#define CORE_INCLUDE_FPDFAPI_IPDF_DATA_AVAIL_H_ + +#include "core/include/fxcrt/fx_stream.h" +#include "core/include/fxcrt/fx_system.h" + +class CPDF_Document; +class CPDF_Object; + +class IPDF_DataAvail { + public: + // Must match PDF_DATA_* definitions in public/fpdf_dataavail.h, but cannot + // #include that header. fpdfsdk/src/fpdf_dataavail.cpp has static_asserts + // to make sure the two sets of values match. + enum DocAvailStatus { + DataError = -1, // PDF_DATA_ERROR + DataNotAvailable = 0, // PDF_DATA_NOTAVAIL + DataAvailable = 1, // PDF_DATA_AVAIL + }; + + // Must match PDF_*LINEAR* definitions in public/fpdf_dataavail.h, but cannot + // #include that header. fpdfsdk/src/fpdf_dataavail.cpp has static_asserts + // to make sure the two sets of values match. + enum DocLinearizationStatus { + LinearizationUnknown = -1, // PDF_LINEARIZATION_UNKNOWN + NotLinearized = 0, // PDF_NOT_LINEARIZED + Linearized = 1, // PDF_LINEARIZED + }; + + // Must match PDF_FORM_* definitions in public/fpdf_dataavail.h, but cannot + // #include that header. fpdfsdk/src/fpdf_dataavail.cpp has static_asserts + // to make sure the two sets of values match. + enum DocFormStatus { + FormError = -1, // PDF_FORM_ERROR + FormNotAvailable = 0, // PDF_FORM_NOTAVAIL + FormAvailable = 1, // PDF_FORM_AVAIL + FormNotExist = 2, // PDF_FORM_NOTEXIST + }; + + class FileAvail { + public: + virtual ~FileAvail(); + virtual FX_BOOL IsDataAvail(FX_FILESIZE offset, FX_DWORD size) = 0; + }; + + class DownloadHints { + public: + virtual ~DownloadHints(); + virtual void AddSegment(FX_FILESIZE offset, FX_DWORD size) = 0; + }; + + static IPDF_DataAvail* Create(FileAvail* pFileAvail, IFX_FileRead* pFileRead); + virtual ~IPDF_DataAvail(); + + FileAvail* GetFileAvail() const { return m_pFileAvail; } + IFX_FileRead* GetFileRead() const { return m_pFileRead; } + + virtual DocAvailStatus IsDocAvail(DownloadHints* pHints) = 0; + virtual void SetDocument(CPDF_Document* pDoc) = 0; + virtual DocAvailStatus IsPageAvail(int iPage, DownloadHints* pHints) = 0; + virtual FX_BOOL IsLinearized() = 0; + virtual DocFormStatus IsFormAvail(DownloadHints* pHints) = 0; + virtual DocLinearizationStatus IsLinearizedPDF() = 0; + virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, + FX_DWORD* pSize) = 0; + + protected: + IPDF_DataAvail(FileAvail* pFileAvail, IFX_FileRead* pFileRead); + + FileAvail* m_pFileAvail; + IFX_FileRead* m_pFileRead; +}; + +#endif // CORE_INCLUDE_FPDFAPI_IPDF_DATA_AVAIL_H_ diff --git a/core/include/fpdfdoc/fpdf_ap.h b/core/include/fpdfdoc/fpdf_ap.h index 5f2a3005ea..62e3907593 100644 --- a/core/include/fpdfdoc/fpdf_ap.h +++ b/core/include/fpdfdoc/fpdf_ap.h @@ -7,7 +7,6 @@ #ifndef CORE_INCLUDE_FPDFDOC_FPDF_AP_H_ #define CORE_INCLUDE_FPDFDOC_FPDF_AP_H_ -#include "core/include/fpdfapi/fpdf_parser.h" #include "core/include/fpdfdoc/fpdf_vt.h" class IPVT_FontMap { diff --git a/core/include/fpdfdoc/fpdf_doc.h b/core/include/fpdfdoc/fpdf_doc.h index 836b48c17b..6ba533160a 100644 --- a/core/include/fpdfdoc/fpdf_doc.h +++ b/core/include/fpdfdoc/fpdf_doc.h @@ -11,9 +11,10 @@ #include <memory> #include <vector> -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/fpdf_parser_decode.h" #include "core/include/fpdfapi/fpdf_render.h" +class CFDF_Document; class CFieldTree; class CPDF_AAction; class CPDF_Action; diff --git a/core/include/fpdfdoc/fpdf_vt.h b/core/include/fpdfdoc/fpdf_vt.h index 8a2e7e93aa..dd2e300162 100644 --- a/core/include/fpdfdoc/fpdf_vt.h +++ b/core/include/fpdfdoc/fpdf_vt.h @@ -7,7 +7,6 @@ #ifndef CORE_INCLUDE_FPDFDOC_FPDF_VT_H_ #define CORE_INCLUDE_FPDFDOC_FPDF_VT_H_ -#include "core/include/fpdfapi/fpdf_parser.h" #include "core/include/fxge/fx_dib.h" class IPDF_VariableText; diff --git a/core/include/fpdftext/fpdf_text.h b/core/include/fpdftext/fpdf_text.h index 7c1cde6051..a3457fcf06 100644 --- a/core/include/fpdftext/fpdf_text.h +++ b/core/include/fpdftext/fpdf_text.h @@ -7,7 +7,8 @@ #ifndef CORE_INCLUDE_FPDFTEXT_FPDF_TEXT_H_ #define CORE_INCLUDE_FPDFTEXT_FPDF_TEXT_H_ -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fxcrt/fx_coordinates.h" +#include "core/include/fxcrt/fx_system.h" class CPDF_Page; class CPDF_TextObject; diff --git a/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp b/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp index ad19b5d685..cb3f8810ac 100644 --- a/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp +++ b/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp @@ -7,6 +7,7 @@ #include "core/include/fpdfapi/cpdf_document.h" #include "core/include/fpdfapi/fpdf_module.h" #include "core/include/fpdfapi/fpdf_page.h" +#include "core/include/fpdfapi/fpdf_parser_decode.h" #include "core/include/fpdfapi/fpdf_serial.h" #include "core/src/fpdfapi/fpdf_page/pageint.h" diff --git a/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp b/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp index 848b12fbdd..099a5c208e 100644 --- a/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp +++ b/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp @@ -10,7 +10,7 @@ #include "core/include/fpdfapi/cpdf_document.h" #include "core/include/fpdfapi/cpdf_parser.h" -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/fpdf_parser_decode.h" #include "core/include/fpdfapi/fpdf_serial.h" #include "core/include/fpdfapi/ipdf_crypto_handler.h" #include "core/include/fxcrt/fx_ext.h" @@ -960,7 +960,7 @@ int32_t CPDF_Creator::WriteIndirectObjectToStream(const CPDF_Object* pObj) { if (pDict) { if (pDict == m_pDocument->m_pRootDict || pDict == m_pEncryptDict) return 1; - if (IsSignatureDict(pDict)) + if (pDict->IsSignatureDict()) return 1; if (pDict->GetStringBy("Type") == "Page") return 1; @@ -1226,7 +1226,7 @@ int32_t CPDF_Creator::WriteDirectObj(FX_DWORD objnum, } m_Offset += 2; const CPDF_Dictionary* p = pObj->AsDictionary(); - bool bSignDict = IsSignatureDict(p); + bool bSignDict = p->IsSignatureDict(); for (const auto& it : *p) { FX_BOOL bSignValue = FALSE; const CFX_ByteString& key = it.first; diff --git a/core/src/fpdfapi/fpdf_font/fpdf_font_charset.cpp b/core/src/fpdfapi/fpdf_font/fpdf_font_charset.cpp index f6d1e2ab92..a4167914d1 100644 --- a/core/src/fpdfapi/fpdf_font/fpdf_font_charset.cpp +++ b/core/src/fpdfapi/fpdf_font/fpdf_font_charset.cpp @@ -5,7 +5,7 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "core/include/fpdfapi/fpdf_page.h" -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/fpdf_parser_decode.h" #include "core/include/fpdfapi/fpdf_resource.h" #include "core/include/fxge/fx_freetype.h" diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp index 2dffc09f9f..5ef5b48af3 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -11,6 +11,7 @@ #include "core/include/fpdfapi/cpdf_document.h" #include "core/include/fpdfapi/fpdf_module.h" #include "core/include/fpdfapi/fpdf_page.h" +#include "core/include/fpdfapi/fpdf_parser_decode.h" #include "core/include/fpdfapi/fpdf_serial.h" namespace { diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp index 87e65c4190..8bfb8b2f6b 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp @@ -11,6 +11,7 @@ #include "core/include/fpdfapi/cpdf_document.h" #include "core/include/fpdfapi/fpdf_module.h" #include "core/include/fpdfapi/fpdf_page.h" +#include "core/include/fpdfapi/fpdf_parser_decode.h" #include "core/include/fxcodec/fx_codec.h" #include "core/include/fxcrt/fx_ext.h" #include "core/include/fxcrt/fx_safe_types.h" diff --git a/core/src/fpdfapi/fpdf_page/pageint.h b/core/src/fpdfapi/fpdf_page/pageint.h index e8d155b656..030e734edd 100644 --- a/core/src/fpdfapi/fpdf_page/pageint.h +++ b/core/src/fpdfapi/fpdf_page/pageint.h @@ -17,6 +17,7 @@ class CPDF_AllStates; class CPDF_ParseOptions; +class CPDF_IccProfile; #define PARSE_STEP_LIMIT 100 diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp b/core/src/fpdfapi/fpdf_parser/cfdf_document.cpp index c87fd63a28..c2a6e33604 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp +++ b/core/src/fpdfapi/fpdf_parser/cfdf_document.cpp @@ -4,7 +4,7 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/cfdf_document.h" #include "core/include/fpdfapi/fpdf_serial.h" #include "core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h" diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_data_avail.cpp index 0d62e4d3ed..19905f871f 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp +++ b/core/src/fpdfapi/fpdf_parser/cpdf_data_avail.cpp @@ -1,206 +1,29 @@ -// Copyright 2014 PDFium Authors. All rights reserved. +// Copyright 2016 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#include "core/include/fpdfapi/fpdf_parser.h" - -#include <algorithm> -#include <memory> -#include <set> -#include <utility> -#include <vector> - #include "core/include/fpdfapi/cpdf_document.h" -#include "core/include/fpdfapi/cpdf_parser.h" -#include "core/include/fpdfapi/fpdf_module.h" -#include "core/include/fpdfapi/fpdf_page.h" +#include "core/include/fpdfapi/fpdf_objects.h" #include "core/include/fxcrt/fx_ext.h" #include "core/include/fxcrt/fx_safe_types.h" -#include "core/src/fpdfapi/fpdf_page/pageint.h" -#include "core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h" +#include "core/src/fpdfapi/fpdf_parser/cpdf_data_avail.h" #include "core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.h" -#include "core/src/fpdfapi/fpdf_parser/parser_int.h" #include "third_party/base/stl_util.h" -namespace { - -bool CanReadFromBitStream(const CFX_BitStream* hStream, - const FX_SAFE_DWORD& num_bits) { - return num_bits.IsValid() && - hStream->BitsRemaining() >= num_bits.ValueOrDie(); -} - -} // namespace +IPDF_DataAvail::IPDF_DataAvail(IPDF_DataAvail::FileAvail* pFileAvail, + IFX_FileRead* pFileRead) + : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} -bool IsSignatureDict(const CPDF_Dictionary* pDict) { - CPDF_Object* pType = pDict->GetElementValue("Type"); - if (!pType) - pType = pDict->GetElementValue("FT"); - return pType && pType->GetString() == "Sig"; -} +IPDF_DataAvail::~IPDF_DataAvail() {} +IPDF_DataAvail::FileAvail::~FileAvail() {} -class CPDF_DataAvail final : public IPDF_DataAvail { - public: - CPDF_DataAvail(IFX_FileAvail* pFileAvail, - IFX_FileRead* pFileRead, - FX_BOOL bSupportHintTable); - ~CPDF_DataAvail() override; - - // IPDF_DataAvail: - DocAvailStatus IsDocAvail(IFX_DownloadHints* pHints) override; - void SetDocument(CPDF_Document* pDoc) override; - DocAvailStatus IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; - DocFormStatus IsFormAvail(IFX_DownloadHints* pHints) override; - DocLinearizationStatus IsLinearizedPDF() override; - FX_BOOL IsLinearized() override { return m_bLinearized; } - void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, FX_DWORD* pSize) override; - - int GetPageCount() const; - CPDF_Dictionary* GetPage(int index); - - friend class CPDF_HintTables; - - protected: - static const int kMaxDataAvailRecursionDepth = 64; - static int s_CurrentDataAvailRecursionDepth; - static const int kMaxPageRecursionDepth = 1024; - - FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); - FX_BOOL IsObjectsAvail(CFX_ArrayTemplate<CPDF_Object*>& obj_array, - FX_BOOL bParsePage, - IFX_DownloadHints* pHints, - CFX_ArrayTemplate<CPDF_Object*>& ret_array); - FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints); - FX_BOOL CheckHeader(IFX_DownloadHints* pHints); - FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints); - FX_BOOL CheckHintTables(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); - - int32_t CheckCrossRefStream(IFX_DownloadHints* pHints, - FX_FILESIZE& xref_offset); - FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); - void SetStartOffset(FX_FILESIZE dwOffset); - FX_BOOL GetNextToken(CFX_ByteString& token); - FX_BOOL GetNextChar(uint8_t& ch); - CPDF_Object* ParseIndirectObjectAt( - FX_FILESIZE pos, - FX_DWORD objnum, - CPDF_IndirectObjectHolder* pObjList = nullptr); - 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); - DocAvailStatus CheckLinearizedData(IFX_DownloadHints* pHints); - FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints); - - DocAvailStatus CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints); - FX_BOOL HaveResourceAncestor(CPDF_Dictionary* pDict); - FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHints* pHints); - FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); - FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints); - FX_BOOL CheckPageNode(CPDF_PageNode& pageNodes, - int32_t iPage, - int32_t& iCount, - IFX_DownloadHints* pHints, - int level); - 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); - bool IsFirstCheck(int iPage); - void ResetFirstCheck(int iPage); - FX_BOOL IsDataAvail(FX_FILESIZE offset, - FX_DWORD size, - IFX_DownloadHints* pHints); - - CPDF_Parser m_parser; - CPDF_SyntaxParser m_syntaxParser; - CPDF_Object* m_pRoot; - FX_DWORD m_dwRootObjNum; - FX_DWORD m_dwInfoObjNum; - CPDF_Object* m_pLinearized; - CPDF_Object* m_pTrailer; - FX_BOOL m_bDocAvail; - FX_FILESIZE m_dwHeaderOffset; - FX_FILESIZE m_dwLastXRefOffset; - FX_FILESIZE m_dwXRefOffset; - FX_FILESIZE m_dwTrailerOffset; - FX_FILESIZE m_dwCurrentOffset; - PDF_DATAAVAIL_STATUS m_docStatus; - FX_FILESIZE m_dwFileLen; - CPDF_Document* m_pDocument; - std::set<FX_DWORD> m_ObjectSet; - CFX_ArrayTemplate<CPDF_Object*> m_objs_array; - FX_FILESIZE m_Pos; - FX_FILESIZE m_bufferOffset; - FX_DWORD m_bufferSize; - CFX_ByteString m_WordBuf; - uint8_t m_bufferData[512]; - CFX_DWordArray m_XRefStreamList; - CFX_DWordArray m_PageObjList; - FX_DWORD m_PagesObjNum; - FX_BOOL m_bLinearized; - FX_DWORD m_dwFirstPageNo; - FX_BOOL m_bLinearedDataOK; - FX_BOOL m_bMainXRefLoadTried; - FX_BOOL m_bMainXRefLoadedOK; - FX_BOOL m_bPagesTreeLoad; - FX_BOOL m_bPagesLoad; - CPDF_Parser* m_pCurrentParser; - FX_FILESIZE m_dwCurrentXRefSteam; - FX_BOOL m_bAnnotsLoad; - FX_BOOL m_bHaveAcroForm; - FX_DWORD m_dwAcroFormObjNum; - FX_BOOL m_bAcroFormLoad; - CPDF_Object* m_pAcroForm; - CFX_ArrayTemplate<CPDF_Object*> m_arrayAcroforms; - CPDF_Dictionary* m_pPageDict; - CPDF_Object* m_pPageResource; - FX_BOOL m_bNeedDownLoadResource; - FX_BOOL m_bPageLoadedOK; - FX_BOOL m_bLinearizedFormParamLoad; - CFX_ArrayTemplate<CPDF_Object*> m_PagesArray; - FX_DWORD m_dwEncryptObjNum; - FX_FILESIZE m_dwPrevXRefOffset; - FX_BOOL m_bTotalLoadPageTree; - FX_BOOL m_bCurPageDictLoadOK; - CPDF_PageNode m_pageNodes; - std::set<FX_DWORD> m_pageMapCheckState; - std::set<FX_DWORD> m_pagesLoadState; - std::unique_ptr<CPDF_HintTables> m_pHintTables; - FX_BOOL m_bSupportHintTable; -}; - -IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, - IFX_FileRead* pFileRead) - : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} +IPDF_DataAvail::DownloadHints::~DownloadHints() {} // static -IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, +IPDF_DataAvail* IPDF_DataAvail::Create(IPDF_DataAvail::FileAvail* pFileAvail, IFX_FileRead* pFileRead) { return new CPDF_DataAvail(pFileAvail, pFileRead, TRUE); } @@ -208,7 +31,7 @@ IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, // static int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; -CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, +CPDF_DataAvail::CPDF_DataAvail(IPDF_DataAvail::FileAvail* pFileAvail, IFX_FileRead* pFileRead, FX_BOOL bSupportHintTable) : IPDF_DataAvail(pFileAvail, pFileRead) { @@ -304,7 +127,7 @@ FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { FX_BOOL CPDF_DataAvail::IsObjectsAvail( CFX_ArrayTemplate<CPDF_Object*>& obj_array, FX_BOOL bParsePage, - IFX_DownloadHints* pHints, + IPDF_DataAvail::DownloadHints* pHints, CFX_ArrayTemplate<CPDF_Object*>& ret_array) { if (!obj_array.GetSize()) return TRUE; @@ -382,7 +205,7 @@ FX_BOOL CPDF_DataAvail::IsObjectsAvail( } IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsDocAvail( - IFX_DownloadHints* pHints) { + IPDF_DataAvail::DownloadHints* pHints) { if (!m_dwFileLen && m_pFileRead) { m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); if (!m_dwFileLen) @@ -397,7 +220,8 @@ IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsDocAvail( return DataAvailable; } -FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject( + IPDF_DataAvail::DownloadHints* pHints) { if (!m_objs_array.GetSize()) { m_objs_array.RemoveAll(); m_ObjectSet.clear(); @@ -424,7 +248,7 @@ FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) { return bRet; } -FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckAcroForm(IPDF_DataAvail::DownloadHints* pHints) { FX_BOOL bExist = FALSE; m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist); if (!bExist) { @@ -445,7 +269,7 @@ FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints) { return TRUE; } -FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckDocStatus(IPDF_DataAvail::DownloadHints* pHints) { switch (m_docStatus) { case PDF_DATAAVAIL_HEADER: return CheckHeader(pHints); @@ -495,7 +319,7 @@ FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { } } -FX_BOOL CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckPageStatus(IPDF_DataAvail::DownloadHints* pHints) { switch (m_docStatus) { case PDF_DATAAVAIL_PAGETREE: return CheckPages(pHints); @@ -510,7 +334,7 @@ FX_BOOL CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints) { } } -FX_BOOL CPDF_DataAvail::LoadAllFile(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::LoadAllFile(IPDF_DataAvail::DownloadHints* pHints) { if (m_pFileAvail->IsDataAvail(0, (FX_DWORD)m_dwFileLen)) { m_docStatus = PDF_DATAAVAIL_DONE; return TRUE; @@ -520,7 +344,7 @@ FX_BOOL CPDF_DataAvail::LoadAllFile(IFX_DownloadHints* pHints) { return FALSE; } -FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::LoadAllXref(IPDF_DataAvail::DownloadHints* pHints) { m_parser.m_pSyntax->InitParser(m_pFileRead, (FX_DWORD)m_dwHeaderOffset); m_parser.m_bOwnFileRead = false; if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) && @@ -537,7 +361,7 @@ FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints) { } CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, - IFX_DownloadHints* pHints, + IPDF_DataAvail::DownloadHints* pHints, FX_BOOL* pExistInFile) { CPDF_Object* pRet = nullptr; FX_DWORD size = 0; @@ -568,7 +392,7 @@ CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, return pRet; } -FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckInfo(IPDF_DataAvail::DownloadHints* pHints) { FX_BOOL bExist = FALSE; CPDF_Object* pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist); if (!bExist) { @@ -597,7 +421,7 @@ FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) { return TRUE; } -FX_BOOL CPDF_DataAvail::CheckRoot(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckRoot(IPDF_DataAvail::DownloadHints* pHints) { FX_BOOL bExist = FALSE; m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist); if (!bExist) { @@ -665,7 +489,7 @@ void CPDF_DataAvail::ResetFirstCheck(int iPage) { m_pageMapCheckState.erase(iPage); } -FX_BOOL CPDF_DataAvail::CheckPage(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckPage(IPDF_DataAvail::DownloadHints* pHints) { FX_DWORD iPageObjs = m_PageObjList.GetSize(); CFX_DWordArray UnavailObjList; for (FX_DWORD i = 0; i < iPageObjs; ++i) { @@ -763,7 +587,7 @@ FX_BOOL CPDF_DataAvail::GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages) { return TRUE; } -FX_BOOL CPDF_DataAvail::CheckPages(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckPages(IPDF_DataAvail::DownloadHints* pHints) { FX_BOOL bExist = FALSE; CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist); if (!bExist) { @@ -790,7 +614,7 @@ FX_BOOL CPDF_DataAvail::CheckPages(IFX_DownloadHints* pHints) { return TRUE; } -FX_BOOL CPDF_DataAvail::CheckHeader(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckHeader(IPDF_DataAvail::DownloadHints* pHints) { FX_DWORD req_size = 1024; if ((FX_FILESIZE)req_size > m_dwFileLen) req_size = (FX_DWORD)m_dwFileLen; @@ -813,7 +637,7 @@ FX_BOOL CPDF_DataAvail::CheckHeader(IFX_DownloadHints* pHints) { return FALSE; } -FX_BOOL CPDF_DataAvail::CheckFirstPage(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckFirstPage(IPDF_DataAvail::DownloadHints* pHints) { CPDF_Dictionary* pDict = m_pLinearized->GetDict(); CPDF_Object* pEndOffSet = pDict ? pDict->GetElement("E") : NULL; if (!pEndOffSet) { @@ -883,7 +707,7 @@ FX_BOOL CPDF_DataAvail::CheckFirstPage(IFX_DownloadHints* pHints) { FX_BOOL CPDF_DataAvail::IsDataAvail(FX_FILESIZE offset, FX_DWORD size, - IFX_DownloadHints* pHints) { + IPDF_DataAvail::DownloadHints* pHints) { if (offset > m_dwFileLen) return TRUE; @@ -902,7 +726,7 @@ FX_BOOL CPDF_DataAvail::IsDataAvail(FX_FILESIZE offset, return TRUE; } -FX_BOOL CPDF_DataAvail::CheckHintTables(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckHintTables(IPDF_DataAvail::DownloadHints* pHints) { CPDF_Dictionary* pDict = m_pLinearized->GetDict(); if (!pDict) { m_docStatus = PDF_DATAAVAIL_ERROR; @@ -1050,7 +874,7 @@ FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { return FALSE; } -FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckEnd(IPDF_DataAvail::DownloadHints* pHints) { FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0); FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos); @@ -1092,8 +916,9 @@ FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) { return FALSE; } -int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, - FX_FILESIZE& xref_offset) { +int32_t CPDF_DataAvail::CheckCrossRefStream( + IPDF_DataAvail::DownloadHints* pHints, + FX_FILESIZE& xref_offset) { xref_offset = 0; FX_DWORD req_size = (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); @@ -1248,7 +1073,8 @@ FX_BOOL CPDF_DataAvail::GetNextChar(uint8_t& ch) { return TRUE; } -FX_BOOL CPDF_DataAvail::CheckCrossRefItem(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckCrossRefItem( + IPDF_DataAvail::DownloadHints* pHints) { int32_t iSize = 0; CFX_ByteString token; while (1) { @@ -1266,7 +1092,8 @@ FX_BOOL CPDF_DataAvail::CheckCrossRefItem(IFX_DownloadHints* pHints) { } } -FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream( + IPDF_DataAvail::DownloadHints* pHints) { FX_FILESIZE xref_offset = 0; int32_t nRet = CheckCrossRefStream(pHints, xref_offset); @@ -1285,7 +1112,7 @@ FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(IFX_DownloadHints* pHints) { return FALSE; } -FX_BOOL CPDF_DataAvail::CheckCrossRef(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckCrossRef(IPDF_DataAvail::DownloadHints* pHints) { int32_t iSize = 0; CFX_ByteString token; if (!GetNextToken(token)) { @@ -1317,7 +1144,8 @@ FX_BOOL CPDF_DataAvail::CheckCrossRef(IFX_DownloadHints* pHints) { return FALSE; } -FX_BOOL CPDF_DataAvail::CheckTrailerAppend(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckTrailerAppend( + IPDF_DataAvail::DownloadHints* pHints) { if (m_Pos < m_dwFileLen) { FX_FILESIZE dwAppendPos = m_Pos + m_syntaxParser.SavePos(); int32_t iSize = (int32_t)( @@ -1338,7 +1166,7 @@ FX_BOOL CPDF_DataAvail::CheckTrailerAppend(IFX_DownloadHints* pHints) { return TRUE; } -FX_BOOL CPDF_DataAvail::CheckTrailer(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckTrailer(IPDF_DataAvail::DownloadHints* pHints) { int32_t iTrailerSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) { @@ -1398,7 +1226,8 @@ FX_BOOL CPDF_DataAvail::CheckTrailer(IFX_DownloadHints* pHints) { return FALSE; } -FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, + IPDF_DataAvail::DownloadHints* pHints) { while (TRUE) { switch (m_docStatus) { case PDF_DATAAVAIL_PAGETREE: @@ -1421,9 +1250,10 @@ FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) { } } -FX_BOOL CPDF_DataAvail::CheckArrayPageNode(FX_DWORD dwPageNo, - CPDF_PageNode* pPageNode, - IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckArrayPageNode( + FX_DWORD dwPageNo, + CPDF_DataAvail::PageNode* pPageNode, + IPDF_DataAvail::DownloadHints* pHints) { FX_BOOL bExist = FALSE; CPDF_Object* pPages = GetObject(dwPageNo, pHints, &bExist); if (!bExist) { @@ -1452,7 +1282,7 @@ FX_BOOL CPDF_DataAvail::CheckArrayPageNode(FX_DWORD dwPageNo, if (!pKid) continue; - CPDF_PageNode* pNode = new CPDF_PageNode(); + PageNode* pNode = new PageNode(); pPageNode->m_childNode.Add(pNode); pNode->m_dwPageNo = pKid->GetRefObjNum(); } @@ -1460,9 +1290,10 @@ FX_BOOL CPDF_DataAvail::CheckArrayPageNode(FX_DWORD dwPageNo, return TRUE; } -FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo, - CPDF_PageNode* pPageNode, - IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckUnkownPageNode( + FX_DWORD dwPageNo, + CPDF_DataAvail::PageNode* pPageNode, + IPDF_DataAvail::DownloadHints* pHints) { FX_BOOL bExist = FALSE; CPDF_Object* pPage = GetObject(dwPageNo, pHints, &bExist); if (!bExist) { @@ -1503,7 +1334,7 @@ FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo, switch (pKids->GetType()) { case CPDF_Object::REFERENCE: { CPDF_Reference* pKid = pKids->AsReference(); - CPDF_PageNode* pNode = new CPDF_PageNode(); + PageNode* pNode = new PageNode(); pPageNode->m_childNode.Add(pNode); pNode->m_dwPageNo = pKid->GetRefObjNum(); } break; @@ -1514,7 +1345,7 @@ FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo, if (!pKid) continue; - CPDF_PageNode* pNode = new CPDF_PageNode(); + PageNode* pNode = new PageNode(); pPageNode->m_childNode.Add(pNode); pNode->m_dwPageNo = pKid->GetRefObjNum(); } @@ -1533,10 +1364,10 @@ FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo, return TRUE; } -FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_PageNode& pageNodes, +FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_DataAvail::PageNode& pageNodes, int32_t iPage, int32_t& iCount, - IFX_DownloadHints* pHints, + IPDF_DataAvail::DownloadHints* pHints, int level) { if (level >= kMaxPageRecursionDepth) return FALSE; @@ -1548,7 +1379,7 @@ FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_PageNode& pageNodes, } for (int32_t i = 0; i < iSize; ++i) { - CPDF_PageNode* pNode = pageNodes.m_childNode.GetAt(i); + PageNode* pNode = pageNodes.m_childNode.GetAt(i); if (!pNode) continue; @@ -1583,7 +1414,8 @@ FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_PageNode& pageNodes, return TRUE; } -FX_BOOL CPDF_DataAvail::LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::LoadDocPage(int32_t iPage, + IPDF_DataAvail::DownloadHints* pHints) { if (m_pDocument->GetPageCount() <= iPage || m_pDocument->m_PageList.GetAt(iPage)) { m_docStatus = PDF_DATAAVAIL_DONE; @@ -1602,7 +1434,7 @@ FX_BOOL CPDF_DataAvail::LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints) { return CheckPageNode(m_pageNodes, iPage, iCount, pHints, 0); } -FX_BOOL CPDF_DataAvail::CheckPageCount(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckPageCount(IPDF_DataAvail::DownloadHints* pHints) { FX_BOOL bExist = FALSE; CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist); if (!bExist) { @@ -1635,7 +1467,7 @@ FX_BOOL CPDF_DataAvail::CheckPageCount(IFX_DownloadHints* pHints) { return FALSE; } -FX_BOOL CPDF_DataAvail::LoadDocPages(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::LoadDocPages(IPDF_DataAvail::DownloadHints* pHints) { if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints)) return FALSE; @@ -1648,7 +1480,7 @@ FX_BOOL CPDF_DataAvail::LoadDocPages(IFX_DownloadHints* pHints) { return FALSE; } -FX_BOOL CPDF_DataAvail::LoadPages(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::LoadPages(IPDF_DataAvail::DownloadHints* pHints) { while (!m_bPagesTreeLoad) { if (!CheckPageStatus(pHints)) return FALSE; @@ -1662,7 +1494,7 @@ FX_BOOL CPDF_DataAvail::LoadPages(IFX_DownloadHints* pHints) { } IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedData( - IFX_DownloadHints* pHints) { + IPDF_DataAvail::DownloadHints* pHints) { if (m_bLinearedDataOK) return DataAvailable; @@ -1695,7 +1527,7 @@ IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedData( } FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage, - IFX_DownloadHints* pHints) { + IPDF_DataAvail::DownloadHints* pHints) { if (!m_objs_array.GetSize()) { m_objs_array.RemoveAll(); m_ObjectSet.clear(); @@ -1729,7 +1561,7 @@ FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage, IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedFirstPage( int32_t iPage, - IFX_DownloadHints* pHints) { + IPDF_DataAvail::DownloadHints* pHints) { if (!m_bAnnotsLoad) { if (!CheckPageAnnots(iPage, pHints)) return DataNotAvailable; @@ -1766,7 +1598,7 @@ FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary* pDict) { IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail( int32_t iPage, - IFX_DownloadHints* pHints) { + IPDF_DataAvail::DownloadHints* pHints) { if (!m_pDocument) return DataError; @@ -1892,7 +1724,7 @@ IPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail( return DataAvailable; } -FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) { +FX_BOOL CPDF_DataAvail::CheckResources(IPDF_DataAvail::DownloadHints* pHints) { if (!m_objs_array.GetSize()) { m_objs_array.RemoveAll(); CFX_ArrayTemplate<CPDF_Object*> obj_array; @@ -1961,7 +1793,7 @@ CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) { } IPDF_DataAvail::DocFormStatus CPDF_DataAvail::IsFormAvail( - IFX_DownloadHints* pHints) { + IPDF_DataAvail::DownloadHints* pHints) { if (!m_pDocument) return FormAvailable; @@ -1995,456 +1827,10 @@ IPDF_DataAvail::DocFormStatus CPDF_DataAvail::IsFormAvail( return FormAvailable; } -CPDF_PageNode::CPDF_PageNode() : m_type(PDF_PAGENODE_UNKNOWN) {} +CPDF_DataAvail::PageNode::PageNode() : m_type(PDF_PAGENODE_UNKNOWN) {} -CPDF_PageNode::~CPDF_PageNode() { +CPDF_DataAvail::PageNode::~PageNode() { for (int32_t i = 0; i < m_childNode.GetSize(); ++i) delete m_childNode[i]; m_childNode.RemoveAll(); } - -CPDF_HintTables::~CPDF_HintTables() { - m_dwDeltaNObjsArray.RemoveAll(); - m_dwNSharedObjsArray.RemoveAll(); - m_dwSharedObjNumArray.RemoveAll(); - m_dwIdentifierArray.RemoveAll(); -} - -FX_DWORD CPDF_HintTables::GetItemLength( - int index, - const std::vector<FX_FILESIZE>& szArray) { - if (index < 0 || szArray.size() < 2 || - static_cast<size_t>(index) > szArray.size() - 2 || - szArray[index] > szArray[index + 1]) { - return 0; - } - return szArray[index + 1] - szArray[index]; -} - -FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { - if (!hStream || hStream->IsEOF()) - return FALSE; - - int nStreamOffset = ReadPrimaryHintStreamOffset(); - int nStreamLen = ReadPrimaryHintStreamLength(); - if (nStreamOffset < 0 || nStreamLen < 1) - return FALSE; - - const FX_DWORD kHeaderSize = 288; - if (hStream->BitsRemaining() < kHeaderSize) - return FALSE; - - // Item 1: The least number of objects in a page. - FX_DWORD dwObjLeastNum = hStream->GetBits(32); - - // Item 2: The location of the first page's page object. - FX_DWORD dwFirstObjLoc = hStream->GetBits(32); - if (dwFirstObjLoc > nStreamOffset) { - FX_SAFE_DWORD safeLoc = pdfium::base::checked_cast<FX_DWORD>(nStreamLen); - safeLoc += dwFirstObjLoc; - if (!safeLoc.IsValid()) - return FALSE; - m_szFirstPageObjOffset = - pdfium::base::checked_cast<FX_FILESIZE>(safeLoc.ValueOrDie()); - } else { - m_szFirstPageObjOffset = - pdfium::base::checked_cast<FX_FILESIZE>(dwFirstObjLoc); - } - - // Item 3: The number of bits needed to represent the difference - // between the greatest and least number of objects in a page. - FX_DWORD dwDeltaObjectsBits = hStream->GetBits(16); - - // Item 4: The least length of a page in bytes. - FX_DWORD dwPageLeastLen = hStream->GetBits(32); - - // Item 5: The number of bits needed to represent the difference - // between the greatest and least length of a page, in bytes. - FX_DWORD dwDeltaPageLenBits = hStream->GetBits(16); - - // Skip Item 6, 7, 8, 9 total 96 bits. - hStream->SkipBits(96); - - // Item 10: The number of bits needed to represent the greatest - // number of shared object references. - FX_DWORD dwSharedObjBits = hStream->GetBits(16); - - // Item 11: The number of bits needed to represent the numerically - // greatest shared object identifier used by the pages. - FX_DWORD dwSharedIdBits = hStream->GetBits(16); - - // Item 12: The number of bits needed to represent the numerator of - // the fractional position for each shared object reference. For each - // shared object referenced from a page, there is an indication of - // where in the page's content stream the object is first referenced. - FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16); - - // Item 13: Skip Item 13 which has 16 bits. - hStream->SkipBits(16); - - CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue("N"); - int nPages = pPageNum ? pPageNum->GetInteger() : 0; - if (nPages < 1) - return FALSE; - - FX_SAFE_DWORD required_bits = dwDeltaObjectsBits; - required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); - if (!CanReadFromBitStream(hStream, required_bits)) - return FALSE; - - for (int i = 0; i < nPages; ++i) { - FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); - safeDeltaObj += dwObjLeastNum; - if (!safeDeltaObj.IsValid()) - return FALSE; - m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); - } - hStream->ByteAlign(); - - required_bits = dwDeltaPageLenBits; - required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); - if (!CanReadFromBitStream(hStream, required_bits)) - return FALSE; - - CFX_DWordArray dwPageLenArray; - for (int i = 0; i < nPages; ++i) { - FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); - safePageLen += dwPageLeastLen; - if (!safePageLen.IsValid()) - return FALSE; - dwPageLenArray.Add(safePageLen.ValueOrDie()); - } - - CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue("E"); - int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1; - if (nOffsetE < 0) - return FALSE; - - CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetElementValue("P"); - int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; - for (int i = 0; i < nPages; ++i) { - if (i == nFirstPageNum) { - m_szPageOffsetArray.push_back(m_szFirstPageObjOffset); - } else if (i == nFirstPageNum + 1) { - if (i == 1) { - m_szPageOffsetArray.push_back(nOffsetE); - } else { - m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 2] + - dwPageLenArray[i - 2]); - } - } else { - if (i == 0) { - m_szPageOffsetArray.push_back(nOffsetE); - } else { - m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 1] + - dwPageLenArray[i - 1]); - } - } - } - - if (nPages > 0) { - m_szPageOffsetArray.push_back(m_szPageOffsetArray[nPages - 1] + - dwPageLenArray[nPages - 1]); - } - hStream->ByteAlign(); - - // Number of shared objects. - required_bits = dwSharedObjBits; - required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); - if (!CanReadFromBitStream(hStream, required_bits)) - return FALSE; - - for (int i = 0; i < nPages; i++) - m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); - hStream->ByteAlign(); - - // Array of identifiers, size = nshared_objects. - for (int i = 0; i < nPages; i++) { - required_bits = dwSharedIdBits; - required_bits *= m_dwNSharedObjsArray[i]; - if (!CanReadFromBitStream(hStream, required_bits)) - return FALSE; - - for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) - m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); - } - hStream->ByteAlign(); - - for (int i = 0; i < nPages; i++) { - FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; - safeSize *= dwSharedNumeratorBits; - if (!CanReadFromBitStream(hStream, safeSize)) - return FALSE; - - hStream->SkipBits(safeSize.ValueOrDie()); - } - hStream->ByteAlign(); - - FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); - safeTotalPageLen *= dwDeltaPageLenBits; - if (!CanReadFromBitStream(hStream, safeTotalPageLen)) - return FALSE; - - hStream->SkipBits(safeTotalPageLen.ValueOrDie()); - hStream->ByteAlign(); - return TRUE; -} - -FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, - FX_DWORD offset) { - if (!hStream || hStream->IsEOF()) - return FALSE; - - int nStreamOffset = ReadPrimaryHintStreamOffset(); - int nStreamLen = ReadPrimaryHintStreamLength(); - if (nStreamOffset < 0 || nStreamLen < 1) - return FALSE; - - FX_SAFE_DWORD bit_offset = offset; - bit_offset *= 8; - if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie()) - return FALSE; - hStream->SkipBits(bit_offset.ValueOrDie() - hStream->GetPos()); - - const FX_DWORD kHeaderSize = 192; - if (hStream->BitsRemaining() < kHeaderSize) - return FALSE; - - // Item 1: The object number of the first object in the shared objects - // section. - FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32); - - // Item 2: The location of the first object in the shared objects section. - FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32); - if (dwFirstSharedObjLoc > nStreamOffset) - dwFirstSharedObjLoc += nStreamLen; - - // Item 3: The number of shared object entries for the first page. - m_nFirstPageSharedObjs = hStream->GetBits(32); - - // Item 4: The number of shared object entries for the shared objects - // section, including the number of shared object entries for the first page. - FX_DWORD dwSharedObjTotal = hStream->GetBits(32); - - // Item 5: The number of bits needed to represent the greatest number of - // objects in a shared object group. Skipped. - hStream->SkipBits(16); - - // Item 6: The least length of a shared object group in bytes. - FX_DWORD dwGroupLeastLen = hStream->GetBits(32); - - // Item 7: The number of bits needed to represent the difference between the - // greatest and least length of a shared object group, in bytes. - FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); - CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetElementValue("O"); - int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; - if (nFirstPageObjNum < 0) - return FALSE; - - FX_DWORD dwPrevObjLen = 0; - FX_DWORD dwCurObjLen = 0; - FX_SAFE_DWORD required_bits = dwSharedObjTotal; - required_bits *= dwDeltaGroupLen; - if (!CanReadFromBitStream(hStream, required_bits)) - return FALSE; - - for (int i = 0; i < dwSharedObjTotal; ++i) { - dwPrevObjLen = dwCurObjLen; - FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen); - safeObjLen += dwGroupLeastLen; - if (!safeObjLen.IsValid()) - return FALSE; - - dwCurObjLen = safeObjLen.ValueOrDie(); - if (i < m_nFirstPageSharedObjs) { - m_dwSharedObjNumArray.Add(nFirstPageObjNum + i); - if (i == 0) - m_szSharedObjOffsetArray.push_back(m_szFirstPageObjOffset); - } else { - FX_SAFE_DWORD safeObjNum = dwFirstSharedObjNum; - safeObjNum += i - m_nFirstPageSharedObjs; - if (!safeObjNum.IsValid()) - return FALSE; - - m_dwSharedObjNumArray.Add(safeObjNum.ValueOrDie()); - if (i == m_nFirstPageSharedObjs) { - m_szSharedObjOffsetArray.push_back( - pdfium::base::checked_cast<int32_t>(dwFirstSharedObjLoc)); - } - } - - if (i != 0 && i != m_nFirstPageSharedObjs) { - FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwPrevObjLen); - safeLoc += m_szSharedObjOffsetArray[i - 1]; - if (!safeLoc.IsValid()) - return FALSE; - - m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie()); - } - } - - if (dwSharedObjTotal > 0) { - FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwCurObjLen); - safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1]; - if (!safeLoc.IsValid()) - return FALSE; - - m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie()); - } - - hStream->ByteAlign(); - if (hStream->BitsRemaining() < dwSharedObjTotal) - return FALSE; - - hStream->SkipBits(dwSharedObjTotal); - hStream->ByteAlign(); - return TRUE; -} - -FX_BOOL CPDF_HintTables::GetPagePos(int index, - FX_FILESIZE& szPageStartPos, - FX_FILESIZE& szPageLength, - FX_DWORD& dwObjNum) { - if (!m_pLinearizedDict) - return FALSE; - - szPageStartPos = m_szPageOffsetArray[index]; - szPageLength = GetItemLength(index, m_szPageOffsetArray); - - CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetElementValue("P"); - int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; - - CPDF_Object* pFirstPageObjNum = m_pLinearizedDict->GetElementValue("O"); - if (!pFirstPageObjNum) - return FALSE; - - int nFirstPageObjNum = pFirstPageObjNum->GetInteger(); - if (index == nFirstPageNum) { - dwObjNum = nFirstPageObjNum; - return TRUE; - } - - // The object number of remaining pages starts from 1. - dwObjNum = 1; - for (int i = 0; i < index; ++i) { - if (i == nFirstPageNum) - continue; - dwObjNum += m_dwDeltaNObjsArray[i]; - } - return TRUE; -} - -IPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage( - int index, - IFX_DownloadHints* pHints) { - if (!m_pLinearizedDict || !pHints) - return IPDF_DataAvail::DataError; - - CPDF_Object* pFirstAvailPage = m_pLinearizedDict->GetElementValue("P"); - int nFirstAvailPage = pFirstAvailPage ? pFirstAvailPage->GetInteger() : 0; - if (index == nFirstAvailPage) - return IPDF_DataAvail::DataAvailable; - - FX_DWORD dwLength = GetItemLength(index, m_szPageOffsetArray); - // If two pages have the same offset, it should be treated as an error. - if (!dwLength) - return IPDF_DataAvail::DataError; - - if (!m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength, pHints)) - return IPDF_DataAvail::DataNotAvailable; - - // Download data of shared objects in the page. - FX_DWORD offset = 0; - for (int i = 0; i < index; ++i) - offset += m_dwNSharedObjsArray[i]; - - CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetElementValue("O"); - int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; - if (nFirstPageObjNum < 0) - return IPDF_DataAvail::DataError; - - FX_DWORD dwIndex = 0; - FX_DWORD dwObjNum = 0; - for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) { - dwIndex = m_dwIdentifierArray[offset + j]; - if (dwIndex >= m_dwSharedObjNumArray.GetSize()) - return IPDF_DataAvail::DataNotAvailable; - - dwObjNum = m_dwSharedObjNumArray[dwIndex]; - if (dwObjNum >= nFirstPageObjNum && - dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) { - continue; - } - - dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray); - // If two objects have the same offset, it should be treated as an error. - if (!dwLength) - return IPDF_DataAvail::DataError; - - if (!m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, - pHints)) { - return IPDF_DataAvail::DataNotAvailable; - } - } - return IPDF_DataAvail::DataAvailable; -} - -FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { - if (!pHintStream || !m_pLinearizedDict) - return FALSE; - - CPDF_Dictionary* pDict = pHintStream->GetDict(); - CPDF_Object* pOffset = pDict ? pDict->GetElement("S") : nullptr; - if (!pOffset || !pOffset->IsNumber()) - return FALSE; - - int shared_hint_table_offset = pOffset->GetInteger(); - CPDF_StreamAcc acc; - acc.LoadAllData(pHintStream); - - FX_DWORD size = acc.GetSize(); - // The header section of page offset hint table is 36 bytes. - // The header section of shared object hint table is 24 bytes. - // Hint table has at least 60 bytes. - const FX_DWORD MIN_STREAM_LEN = 60; - if (size < MIN_STREAM_LEN || shared_hint_table_offset <= 0 || - size < shared_hint_table_offset) { - return FALSE; - } - - CFX_BitStream bs; - bs.Init(acc.GetData(), size); - return ReadPageHintTable(&bs) && - ReadSharedObjHintTable(&bs, pdfium::base::checked_cast<FX_DWORD>( - shared_hint_table_offset)); -} - -int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { - if (!m_pLinearizedDict) - return -1; - - CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); - if (!pRange) - return -1; - - CPDF_Object* pStreamOffset = pRange->GetElementValue(0); - if (!pStreamOffset) - return -1; - - return pStreamOffset->GetInteger(); -} - -int CPDF_HintTables::ReadPrimaryHintStreamLength() const { - if (!m_pLinearizedDict) - return -1; - - CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); - if (!pRange) - return -1; - - CPDF_Object* pStreamLen = pRange->GetElementValue(1); - if (!pStreamLen) - return -1; - - return pStreamLen->GetInteger(); -} diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_data_avail.h b/core/src/fpdfapi/fpdf_parser/cpdf_data_avail.h new file mode 100644 index 0000000000..3fc26c368a --- /dev/null +++ b/core/src/fpdfapi/fpdf_parser/cpdf_data_avail.h @@ -0,0 +1,217 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_SRC_FPDFAPI_FPDF_PARSER_CPDF_DATA_AVAIL_H_ +#define CORE_SRC_FPDFAPI_FPDF_PARSER_CPDF_DATA_AVAIL_H_ + +#include "core/include/fpdfapi/cpdf_parser.h" +#include "core/include/fpdfapi/ipdf_data_avail.h" +#include "core/include/fxcrt/fx_basic.h" +#include "core/src/fpdfapi/fpdf_parser/cpdf_hint_tables.h" +#include "core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h" + +class CPDF_Dictionary; +class CPDF_IndirectObjectHolder; +class CPDF_Parser; + +enum PDF_DATAAVAIL_STATUS { + PDF_DATAAVAIL_HEADER = 0, + PDF_DATAAVAIL_FIRSTPAGE, + PDF_DATAAVAIL_FIRSTPAGE_PREPARE, + PDF_DATAAVAIL_HINTTABLE, + PDF_DATAAVAIL_END, + PDF_DATAAVAIL_CROSSREF, + PDF_DATAAVAIL_CROSSREF_ITEM, + PDF_DATAAVAIL_CROSSREF_STREAM, + PDF_DATAAVAIL_TRAILER, + PDF_DATAAVAIL_LOADALLCROSSREF, + PDF_DATAAVAIL_ROOT, + PDF_DATAAVAIL_INFO, + PDF_DATAAVAIL_ACROFORM, + PDF_DATAAVAIL_ACROFORM_SUBOBJECT, + PDF_DATAAVAIL_PAGETREE, + PDF_DATAAVAIL_PAGE, + PDF_DATAAVAIL_PAGE_LATERLOAD, + PDF_DATAAVAIL_RESOURCES, + PDF_DATAAVAIL_DONE, + PDF_DATAAVAIL_ERROR, + PDF_DATAAVAIL_LOADALLFILE, + PDF_DATAAVAIL_TRAILER_APPEND +}; + +enum PDF_PAGENODE_TYPE { + PDF_PAGENODE_UNKNOWN = 0, + PDF_PAGENODE_PAGE, + PDF_PAGENODE_PAGES, + PDF_PAGENODE_ARRAY, +}; + +class CPDF_DataAvail final : public IPDF_DataAvail { + public: + CPDF_DataAvail(FileAvail* pFileAvail, + IFX_FileRead* pFileRead, + FX_BOOL bSupportHintTable); + ~CPDF_DataAvail() override; + + // IPDF_DataAvail: + DocAvailStatus IsDocAvail(DownloadHints* pHints) override; + void SetDocument(CPDF_Document* pDoc) override; + DocAvailStatus IsPageAvail(int iPage, DownloadHints* pHints) override; + DocFormStatus IsFormAvail(DownloadHints* pHints) override; + DocLinearizationStatus IsLinearizedPDF() override; + FX_BOOL IsLinearized() override { return m_bLinearized; } + void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, FX_DWORD* pSize) override; + + int GetPageCount() const; + CPDF_Dictionary* GetPage(int index); + + friend class CPDF_HintTables; + + protected: + class PageNode { + public: + PageNode(); + ~PageNode(); + + PDF_PAGENODE_TYPE m_type; + FX_DWORD m_dwPageNo; + CFX_ArrayTemplate<PageNode*> m_childNode; + }; + + static const int kMaxDataAvailRecursionDepth = 64; + static int s_CurrentDataAvailRecursionDepth; + static const int kMaxPageRecursionDepth = 1024; + + FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); + FX_BOOL IsObjectsAvail(CFX_ArrayTemplate<CPDF_Object*>& obj_array, + FX_BOOL bParsePage, + IPDF_DataAvail::DownloadHints* pHints, + CFX_ArrayTemplate<CPDF_Object*>& ret_array); + FX_BOOL CheckDocStatus(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckHeader(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckFirstPage(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckHintTables(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckEnd(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckCrossRef(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckCrossRefItem(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckTrailer(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckRoot(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckInfo(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckPages(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckPage(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckResources(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckAnnots(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckAcroForm(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckAcroFormSubObject(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckTrailerAppend(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckPageStatus(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckAllCrossRefStream(IPDF_DataAvail::DownloadHints* pHints); + + int32_t CheckCrossRefStream(IPDF_DataAvail::DownloadHints* pHints, + FX_FILESIZE& xref_offset); + FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); + void SetStartOffset(FX_FILESIZE dwOffset); + FX_BOOL GetNextToken(CFX_ByteString& token); + FX_BOOL GetNextChar(uint8_t& ch); + CPDF_Object* ParseIndirectObjectAt( + FX_FILESIZE pos, + FX_DWORD objnum, + CPDF_IndirectObjectHolder* pObjList = nullptr); + CPDF_Object* GetObject(FX_DWORD objnum, + IPDF_DataAvail::DownloadHints* pHints, + FX_BOOL* pExistInFile); + FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); + FX_BOOL PreparePageItem(); + FX_BOOL LoadPages(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL LoadAllXref(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL LoadAllFile(IPDF_DataAvail::DownloadHints* pHints); + DocAvailStatus CheckLinearizedData(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckPageAnnots(int iPage, IPDF_DataAvail::DownloadHints* pHints); + + DocAvailStatus CheckLinearizedFirstPage( + int iPage, + IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL HaveResourceAncestor(CPDF_Dictionary* pDict); + FX_BOOL CheckPage(int32_t iPage, IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL LoadDocPages(IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL LoadDocPage(int32_t iPage, IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckPageNode(PageNode& pageNodes, + int32_t iPage, + int32_t& iCount, + IPDF_DataAvail::DownloadHints* pHints, + int level); + FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, + PageNode* pPageNode, + IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, + PageNode* pPageNode, + IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL CheckPageCount(IPDF_DataAvail::DownloadHints* pHints); + bool IsFirstCheck(int iPage); + void ResetFirstCheck(int iPage); + FX_BOOL IsDataAvail(FX_FILESIZE offset, + FX_DWORD size, + IPDF_DataAvail::DownloadHints* pHints); + + CPDF_Parser m_parser; + CPDF_SyntaxParser m_syntaxParser; + CPDF_Object* m_pRoot; + FX_DWORD m_dwRootObjNum; + FX_DWORD m_dwInfoObjNum; + CPDF_Object* m_pLinearized; + CPDF_Object* m_pTrailer; + FX_BOOL m_bDocAvail; + FX_FILESIZE m_dwHeaderOffset; + FX_FILESIZE m_dwLastXRefOffset; + FX_FILESIZE m_dwXRefOffset; + FX_FILESIZE m_dwTrailerOffset; + FX_FILESIZE m_dwCurrentOffset; + PDF_DATAAVAIL_STATUS m_docStatus; + FX_FILESIZE m_dwFileLen; + CPDF_Document* m_pDocument; + std::set<FX_DWORD> m_ObjectSet; + CFX_ArrayTemplate<CPDF_Object*> m_objs_array; + FX_FILESIZE m_Pos; + FX_FILESIZE m_bufferOffset; + FX_DWORD m_bufferSize; + CFX_ByteString m_WordBuf; + uint8_t m_bufferData[512]; + CFX_DWordArray m_XRefStreamList; + CFX_DWordArray m_PageObjList; + FX_DWORD m_PagesObjNum; + FX_BOOL m_bLinearized; + FX_DWORD m_dwFirstPageNo; + FX_BOOL m_bLinearedDataOK; + FX_BOOL m_bMainXRefLoadTried; + FX_BOOL m_bMainXRefLoadedOK; + FX_BOOL m_bPagesTreeLoad; + FX_BOOL m_bPagesLoad; + CPDF_Parser* m_pCurrentParser; + FX_FILESIZE m_dwCurrentXRefSteam; + FX_BOOL m_bAnnotsLoad; + FX_BOOL m_bHaveAcroForm; + FX_DWORD m_dwAcroFormObjNum; + FX_BOOL m_bAcroFormLoad; + CPDF_Object* m_pAcroForm; + CFX_ArrayTemplate<CPDF_Object*> m_arrayAcroforms; + CPDF_Dictionary* m_pPageDict; + CPDF_Object* m_pPageResource; + FX_BOOL m_bNeedDownLoadResource; + FX_BOOL m_bPageLoadedOK; + FX_BOOL m_bLinearizedFormParamLoad; + CFX_ArrayTemplate<CPDF_Object*> m_PagesArray; + FX_DWORD m_dwEncryptObjNum; + FX_FILESIZE m_dwPrevXRefOffset; + FX_BOOL m_bTotalLoadPageTree; + FX_BOOL m_bCurPageDictLoadOK; + PageNode m_pageNodes; + std::set<FX_DWORD> m_pageMapCheckState; + std::set<FX_DWORD> m_pagesLoadState; + std::unique_ptr<CPDF_HintTables> m_pHintTables; + FX_BOOL m_bSupportHintTable; +}; + +#endif // CORE_SRC_FPDFAPI_FPDF_PARSER_CPDF_DATA_AVAIL_H_ diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_document.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_document.cpp index e509e36382..394b17334e 100644 --- a/core/src/fpdfapi/fpdf_parser/cpdf_document.cpp +++ b/core/src/fpdfapi/fpdf_parser/cpdf_document.cpp @@ -10,7 +10,6 @@ #include "core/include/fpdfapi/cpdf_parser.h" #include "core/include/fpdfapi/fpdf_module.h" -#include "core/include/fpdfapi/fpdf_parser.h" #include "core/include/fxge/fx_font.h" #include "core/src/fpdfapi/fpdf_render/render_int.h" #include "third_party/base/stl_util.h" diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp new file mode 100644 index 0000000000..09148ba76a --- /dev/null +++ b/core/src/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp @@ -0,0 +1,467 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/src/fpdfapi/fpdf_parser/cpdf_hint_tables.h" + +#include "core/include/fxcrt/fx_safe_types.h" +#include "core/include/fpdfapi/fpdf_objects.h" +#include "core/src/fpdfapi/fpdf_parser/cpdf_data_avail.h" + +namespace { + +bool CanReadFromBitStream(const CFX_BitStream* hStream, + const FX_SAFE_DWORD& num_bits) { + return num_bits.IsValid() && + hStream->BitsRemaining() >= num_bits.ValueOrDie(); +} + +} // namespace + +CPDF_HintTables::~CPDF_HintTables() { + m_dwDeltaNObjsArray.RemoveAll(); + m_dwNSharedObjsArray.RemoveAll(); + m_dwSharedObjNumArray.RemoveAll(); + m_dwIdentifierArray.RemoveAll(); +} + +FX_DWORD CPDF_HintTables::GetItemLength( + int index, + const std::vector<FX_FILESIZE>& szArray) { + if (index < 0 || szArray.size() < 2 || + static_cast<size_t>(index) > szArray.size() - 2 || + szArray[index] > szArray[index + 1]) { + return 0; + } + return szArray[index + 1] - szArray[index]; +} + +FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { + if (!hStream || hStream->IsEOF()) + return FALSE; + + int nStreamOffset = ReadPrimaryHintStreamOffset(); + int nStreamLen = ReadPrimaryHintStreamLength(); + if (nStreamOffset < 0 || nStreamLen < 1) + return FALSE; + + const FX_DWORD kHeaderSize = 288; + if (hStream->BitsRemaining() < kHeaderSize) + return FALSE; + + // Item 1: The least number of objects in a page. + FX_DWORD dwObjLeastNum = hStream->GetBits(32); + + // Item 2: The location of the first page's page object. + FX_DWORD dwFirstObjLoc = hStream->GetBits(32); + if (dwFirstObjLoc > nStreamOffset) { + FX_SAFE_DWORD safeLoc = pdfium::base::checked_cast<FX_DWORD>(nStreamLen); + safeLoc += dwFirstObjLoc; + if (!safeLoc.IsValid()) + return FALSE; + m_szFirstPageObjOffset = + pdfium::base::checked_cast<FX_FILESIZE>(safeLoc.ValueOrDie()); + } else { + m_szFirstPageObjOffset = + pdfium::base::checked_cast<FX_FILESIZE>(dwFirstObjLoc); + } + + // Item 3: The number of bits needed to represent the difference + // between the greatest and least number of objects in a page. + FX_DWORD dwDeltaObjectsBits = hStream->GetBits(16); + + // Item 4: The least length of a page in bytes. + FX_DWORD dwPageLeastLen = hStream->GetBits(32); + + // Item 5: The number of bits needed to represent the difference + // between the greatest and least length of a page, in bytes. + FX_DWORD dwDeltaPageLenBits = hStream->GetBits(16); + + // Skip Item 6, 7, 8, 9 total 96 bits. + hStream->SkipBits(96); + + // Item 10: The number of bits needed to represent the greatest + // number of shared object references. + FX_DWORD dwSharedObjBits = hStream->GetBits(16); + + // Item 11: The number of bits needed to represent the numerically + // greatest shared object identifier used by the pages. + FX_DWORD dwSharedIdBits = hStream->GetBits(16); + + // Item 12: The number of bits needed to represent the numerator of + // the fractional position for each shared object reference. For each + // shared object referenced from a page, there is an indication of + // where in the page's content stream the object is first referenced. + FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16); + + // Item 13: Skip Item 13 which has 16 bits. + hStream->SkipBits(16); + + CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue("N"); + int nPages = pPageNum ? pPageNum->GetInteger() : 0; + if (nPages < 1) + return FALSE; + + FX_SAFE_DWORD required_bits = dwDeltaObjectsBits; + required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); + if (!CanReadFromBitStream(hStream, required_bits)) + return FALSE; + + for (int i = 0; i < nPages; ++i) { + FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); + safeDeltaObj += dwObjLeastNum; + if (!safeDeltaObj.IsValid()) + return FALSE; + m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); + } + hStream->ByteAlign(); + + required_bits = dwDeltaPageLenBits; + required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); + if (!CanReadFromBitStream(hStream, required_bits)) + return FALSE; + + CFX_DWordArray dwPageLenArray; + for (int i = 0; i < nPages; ++i) { + FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); + safePageLen += dwPageLeastLen; + if (!safePageLen.IsValid()) + return FALSE; + dwPageLenArray.Add(safePageLen.ValueOrDie()); + } + + CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue("E"); + int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1; + if (nOffsetE < 0) + return FALSE; + + CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetElementValue("P"); + int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; + for (int i = 0; i < nPages; ++i) { + if (i == nFirstPageNum) { + m_szPageOffsetArray.push_back(m_szFirstPageObjOffset); + } else if (i == nFirstPageNum + 1) { + if (i == 1) { + m_szPageOffsetArray.push_back(nOffsetE); + } else { + m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 2] + + dwPageLenArray[i - 2]); + } + } else { + if (i == 0) { + m_szPageOffsetArray.push_back(nOffsetE); + } else { + m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 1] + + dwPageLenArray[i - 1]); + } + } + } + + if (nPages > 0) { + m_szPageOffsetArray.push_back(m_szPageOffsetArray[nPages - 1] + + dwPageLenArray[nPages - 1]); + } + hStream->ByteAlign(); + + // Number of shared objects. + required_bits = dwSharedObjBits; + required_bits *= pdfium::base::checked_cast<FX_DWORD>(nPages); + if (!CanReadFromBitStream(hStream, required_bits)) + return FALSE; + + for (int i = 0; i < nPages; i++) + m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); + hStream->ByteAlign(); + + // Array of identifiers, size = nshared_objects. + for (int i = 0; i < nPages; i++) { + required_bits = dwSharedIdBits; + required_bits *= m_dwNSharedObjsArray[i]; + if (!CanReadFromBitStream(hStream, required_bits)) + return FALSE; + + for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) + m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); + } + hStream->ByteAlign(); + + for (int i = 0; i < nPages; i++) { + FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; + safeSize *= dwSharedNumeratorBits; + if (!CanReadFromBitStream(hStream, safeSize)) + return FALSE; + + hStream->SkipBits(safeSize.ValueOrDie()); + } + hStream->ByteAlign(); + + FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); + safeTotalPageLen *= dwDeltaPageLenBits; + if (!CanReadFromBitStream(hStream, safeTotalPageLen)) + return FALSE; + + hStream->SkipBits(safeTotalPageLen.ValueOrDie()); + hStream->ByteAlign(); + return TRUE; +} + +FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, + FX_DWORD offset) { + if (!hStream || hStream->IsEOF()) + return FALSE; + + int nStreamOffset = ReadPrimaryHintStreamOffset(); + int nStreamLen = ReadPrimaryHintStreamLength(); + if (nStreamOffset < 0 || nStreamLen < 1) + return FALSE; + + FX_SAFE_DWORD bit_offset = offset; + bit_offset *= 8; + if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie()) + return FALSE; + hStream->SkipBits(bit_offset.ValueOrDie() - hStream->GetPos()); + + const FX_DWORD kHeaderSize = 192; + if (hStream->BitsRemaining() < kHeaderSize) + return FALSE; + + // Item 1: The object number of the first object in the shared objects + // section. + FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32); + + // Item 2: The location of the first object in the shared objects section. + FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32); + if (dwFirstSharedObjLoc > nStreamOffset) + dwFirstSharedObjLoc += nStreamLen; + + // Item 3: The number of shared object entries for the first page. + m_nFirstPageSharedObjs = hStream->GetBits(32); + + // Item 4: The number of shared object entries for the shared objects + // section, including the number of shared object entries for the first page. + FX_DWORD dwSharedObjTotal = hStream->GetBits(32); + + // Item 5: The number of bits needed to represent the greatest number of + // objects in a shared object group. Skipped. + hStream->SkipBits(16); + + // Item 6: The least length of a shared object group in bytes. + FX_DWORD dwGroupLeastLen = hStream->GetBits(32); + + // Item 7: The number of bits needed to represent the difference between the + // greatest and least length of a shared object group, in bytes. + FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); + CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetElementValue("O"); + int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; + if (nFirstPageObjNum < 0) + return FALSE; + + FX_DWORD dwPrevObjLen = 0; + FX_DWORD dwCurObjLen = 0; + FX_SAFE_DWORD required_bits = dwSharedObjTotal; + required_bits *= dwDeltaGroupLen; + if (!CanReadFromBitStream(hStream, required_bits)) + return FALSE; + + for (int i = 0; i < dwSharedObjTotal; ++i) { + dwPrevObjLen = dwCurObjLen; + FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen); + safeObjLen += dwGroupLeastLen; + if (!safeObjLen.IsValid()) + return FALSE; + + dwCurObjLen = safeObjLen.ValueOrDie(); + if (i < m_nFirstPageSharedObjs) { + m_dwSharedObjNumArray.Add(nFirstPageObjNum + i); + if (i == 0) + m_szSharedObjOffsetArray.push_back(m_szFirstPageObjOffset); + } else { + FX_SAFE_DWORD safeObjNum = dwFirstSharedObjNum; + safeObjNum += i - m_nFirstPageSharedObjs; + if (!safeObjNum.IsValid()) + return FALSE; + + m_dwSharedObjNumArray.Add(safeObjNum.ValueOrDie()); + if (i == m_nFirstPageSharedObjs) { + m_szSharedObjOffsetArray.push_back( + pdfium::base::checked_cast<int32_t>(dwFirstSharedObjLoc)); + } + } + + if (i != 0 && i != m_nFirstPageSharedObjs) { + FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwPrevObjLen); + safeLoc += m_szSharedObjOffsetArray[i - 1]; + if (!safeLoc.IsValid()) + return FALSE; + + m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie()); + } + } + + if (dwSharedObjTotal > 0) { + FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwCurObjLen); + safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1]; + if (!safeLoc.IsValid()) + return FALSE; + + m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie()); + } + + hStream->ByteAlign(); + if (hStream->BitsRemaining() < dwSharedObjTotal) + return FALSE; + + hStream->SkipBits(dwSharedObjTotal); + hStream->ByteAlign(); + return TRUE; +} + +FX_BOOL CPDF_HintTables::GetPagePos(int index, + FX_FILESIZE& szPageStartPos, + FX_FILESIZE& szPageLength, + FX_DWORD& dwObjNum) { + if (!m_pLinearizedDict) + return FALSE; + + szPageStartPos = m_szPageOffsetArray[index]; + szPageLength = GetItemLength(index, m_szPageOffsetArray); + + CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetElementValue("P"); + int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; + + CPDF_Object* pFirstPageObjNum = m_pLinearizedDict->GetElementValue("O"); + if (!pFirstPageObjNum) + return FALSE; + + int nFirstPageObjNum = pFirstPageObjNum->GetInteger(); + if (index == nFirstPageNum) { + dwObjNum = nFirstPageObjNum; + return TRUE; + } + + // The object number of remaining pages starts from 1. + dwObjNum = 1; + for (int i = 0; i < index; ++i) { + if (i == nFirstPageNum) + continue; + dwObjNum += m_dwDeltaNObjsArray[i]; + } + return TRUE; +} + +IPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage( + int index, + IPDF_DataAvail::DownloadHints* pHints) { + if (!m_pLinearizedDict || !pHints) + return IPDF_DataAvail::DataError; + + CPDF_Object* pFirstAvailPage = m_pLinearizedDict->GetElementValue("P"); + int nFirstAvailPage = pFirstAvailPage ? pFirstAvailPage->GetInteger() : 0; + if (index == nFirstAvailPage) + return IPDF_DataAvail::DataAvailable; + + FX_DWORD dwLength = GetItemLength(index, m_szPageOffsetArray); + // If two pages have the same offset, it should be treated as an error. + if (!dwLength) + return IPDF_DataAvail::DataError; + + if (!m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength, pHints)) + return IPDF_DataAvail::DataNotAvailable; + + // Download data of shared objects in the page. + FX_DWORD offset = 0; + for (int i = 0; i < index; ++i) + offset += m_dwNSharedObjsArray[i]; + + CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetElementValue("O"); + int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; + if (nFirstPageObjNum < 0) + return IPDF_DataAvail::DataError; + + FX_DWORD dwIndex = 0; + FX_DWORD dwObjNum = 0; + for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) { + dwIndex = m_dwIdentifierArray[offset + j]; + if (dwIndex >= m_dwSharedObjNumArray.GetSize()) + return IPDF_DataAvail::DataNotAvailable; + + dwObjNum = m_dwSharedObjNumArray[dwIndex]; + if (dwObjNum >= nFirstPageObjNum && + dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) { + continue; + } + + dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray); + // If two objects have the same offset, it should be treated as an error. + if (!dwLength) + return IPDF_DataAvail::DataError; + + if (!m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, + pHints)) { + return IPDF_DataAvail::DataNotAvailable; + } + } + return IPDF_DataAvail::DataAvailable; +} + +FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { + if (!pHintStream || !m_pLinearizedDict) + return FALSE; + + CPDF_Dictionary* pDict = pHintStream->GetDict(); + CPDF_Object* pOffset = pDict ? pDict->GetElement("S") : nullptr; + if (!pOffset || !pOffset->IsNumber()) + return FALSE; + + int shared_hint_table_offset = pOffset->GetInteger(); + CPDF_StreamAcc acc; + acc.LoadAllData(pHintStream); + + FX_DWORD size = acc.GetSize(); + // The header section of page offset hint table is 36 bytes. + // The header section of shared object hint table is 24 bytes. + // Hint table has at least 60 bytes. + const FX_DWORD MIN_STREAM_LEN = 60; + if (size < MIN_STREAM_LEN || shared_hint_table_offset <= 0 || + size < shared_hint_table_offset) { + return FALSE; + } + + CFX_BitStream bs; + bs.Init(acc.GetData(), size); + return ReadPageHintTable(&bs) && + ReadSharedObjHintTable(&bs, pdfium::base::checked_cast<FX_DWORD>( + shared_hint_table_offset)); +} + +int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { + if (!m_pLinearizedDict) + return -1; + + CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); + if (!pRange) + return -1; + + CPDF_Object* pStreamOffset = pRange->GetElementValue(0); + if (!pStreamOffset) + return -1; + + return pStreamOffset->GetInteger(); +} + +int CPDF_HintTables::ReadPrimaryHintStreamLength() const { + if (!m_pLinearizedDict) + return -1; + + CPDF_Array* pRange = m_pLinearizedDict->GetArrayBy("H"); + if (!pRange) + return -1; + + CPDF_Object* pStreamLen = pRange->GetElementValue(1); + if (!pStreamLen) + return -1; + + return pStreamLen->GetInteger(); +} diff --git a/core/src/fpdfapi/fpdf_parser/parser_int.h b/core/src/fpdfapi/fpdf_parser/cpdf_hint_tables.h index b4865842ea..2ddad2f655 100644 --- a/core/src/fpdfapi/fpdf_parser/parser_int.h +++ b/core/src/fpdfapi/fpdf_parser/cpdf_hint_tables.h @@ -1,14 +1,15 @@ -// Copyright 2014 PDFium Authors. All rights reserved. +// Copyright 2016 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#ifndef CORE_SRC_FPDFAPI_FPDF_PARSER_PARSER_INT_H_ -#define CORE_SRC_FPDFAPI_FPDF_PARSER_PARSER_INT_H_ +#ifndef CORE_SRC_FPDFAPI_FPDF_PARSER_CPDF_HINT_TABLES_H_ +#define CORE_SRC_FPDFAPI_FPDF_PARSER_CPDF_HINT_TABLES_H_ #include <vector> +#include "core/include/fpdfapi/ipdf_data_avail.h" #include "core/include/fxcrt/fx_basic.h" #include "core/include/fxcrt/fx_stream.h" @@ -16,7 +17,6 @@ class CFX_BitStream; class CPDF_DataAvail; class CPDF_Dictionary; class CPDF_Stream; -class IFX_DownloadHints; class CPDF_HintTables { public: @@ -31,8 +31,11 @@ class CPDF_HintTables { FX_FILESIZE& szPageStartPos, FX_FILESIZE& szPageLength, FX_DWORD& dwObjNum); - IPDF_DataAvail::DocAvailStatus CheckPage(int index, - IFX_DownloadHints* pHints); + + IPDF_DataAvail::DocAvailStatus CheckPage( + int index, + IPDF_DataAvail::DownloadHints* pHints); + FX_BOOL LoadHintStream(CPDF_Stream* pHintStream); protected: @@ -56,4 +59,4 @@ class CPDF_HintTables { std::vector<FX_FILESIZE> m_szSharedObjOffsetArray; }; -#endif // CORE_SRC_FPDFAPI_FPDF_PARSER_PARSER_INT_H_ +#endif // CORE_SRC_FPDFAPI_FPDF_PARSER_CPDF_HINT_TABLES_H_ diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_parser.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_parser.cpp index b016797d7d..2835c6ff38 100644 --- a/core/src/fpdfapi/fpdf_parser/cpdf_parser.cpp +++ b/core/src/fpdfapi/fpdf_parser/cpdf_parser.cpp @@ -9,7 +9,6 @@ #include <vector> #include "core/include/fpdfapi/cpdf_document.h" -#include "core/include/fpdfapi/fpdf_parser.h" #include "core/include/fpdfapi/ipdf_crypto_handler.h" #include "core/include/fxcrt/fx_ext.h" #include "core/include/fxcrt/fx_safe_types.h" diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_parser_embeddertest.cpp index fba4117433..f427ec5d81 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp +++ b/core/src/fpdfapi/fpdf_parser/cpdf_parser_embeddertest.cpp @@ -5,15 +5,15 @@ #include "testing/embedder_test.h" #include "testing/gtest/include/gtest/gtest.h" -class FPDFParserEmbeddertest : public EmbedderTest {}; +class CPDFParserEmbeddertest : public EmbedderTest {}; -TEST_F(FPDFParserEmbeddertest, LoadError_454695) { +TEST_F(CPDFParserEmbeddertest, LoadError_454695) { // Test a dictionary with hex string instead of correct content. // Verify that the defective pdf shouldn't be opened correctly. EXPECT_FALSE(OpenDocument("bug_454695.pdf")); } -TEST_F(FPDFParserEmbeddertest, Bug_481363) { +TEST_F(CPDFParserEmbeddertest, Bug_481363) { // Test colorspace object with malformed dictionary. EXPECT_TRUE(OpenDocument("bug_481363.pdf")); FPDF_PAGE page = LoadPage(0); @@ -21,7 +21,7 @@ TEST_F(FPDFParserEmbeddertest, Bug_481363) { UnloadPage(page); } -TEST_F(FPDFParserEmbeddertest, Bug_544880) { +TEST_F(CPDFParserEmbeddertest, Bug_544880) { // Test self referencing /Pages object. EXPECT_TRUE(OpenDocument("bug_544880.pdf")); // Shouldn't crash. We don't check the return value here because we get the @@ -30,11 +30,11 @@ TEST_F(FPDFParserEmbeddertest, Bug_544880) { (void)GetPageCount(); } -TEST_F(FPDFParserEmbeddertest, Feature_Linearized_Loading) { +TEST_F(CPDFParserEmbeddertest, Feature_Linearized_Loading) { EXPECT_TRUE(OpenDocument("feature_linearized_loading.pdf", true)); } -TEST_F(FPDFParserEmbeddertest, Bug_325) { +TEST_F(CPDFParserEmbeddertest, Bug_325) { EXPECT_FALSE(OpenDocument("bug_325_a.pdf")); EXPECT_FALSE(OpenDocument("bug_325_b.pdf")); } diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_unittest.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_parser_unittest.cpp index 49521b0102..ec84171059 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_unittest.cpp +++ b/core/src/fpdfapi/fpdf_parser/cpdf_parser_unittest.cpp @@ -6,7 +6,6 @@ #include <string> #include "core/include/fpdfapi/cpdf_parser.h" -#include "core/include/fpdfapi/fpdf_parser.h" #include "core/include/fxcrt/fx_stream.h" #include "core/include/fxcrt/fx_ext.h" #include "core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h" @@ -68,171 +67,13 @@ class CPDF_TestParser : public CPDF_Parser { // Add test cases here as private friend so that protected members in // CPDF_Parser can be accessed by test cases. // Need to access RebuildCrossRef. - FRIEND_TEST(fpdf_parser_parser, RebuildCrossRefCorrectly); - FRIEND_TEST(fpdf_parser_parser, RebuildCrossRefFailed); + FRIEND_TEST(cpdf_parser, RebuildCrossRefCorrectly); + FRIEND_TEST(cpdf_parser, RebuildCrossRefFailed); // Need to access LoadCrossRefV4. - FRIEND_TEST(fpdf_parser_parser, LoadCrossRefV4); + FRIEND_TEST(cpdf_parser, LoadCrossRefV4); }; -TEST(fpdf_parser_parser, ReadHexString) { - { - // Empty string. - uint8_t data[] = ""; - ScopedFileStream stream(FX_CreateMemoryStream(data, 0, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("", parser.ReadHexString()); - EXPECT_EQ(0, parser.SavePos()); - } - - { - // Blank string. - uint8_t data[] = " "; - ScopedFileStream stream(FX_CreateMemoryStream(data, 2, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("", parser.ReadHexString()); - EXPECT_EQ(2, parser.SavePos()); - } - - { - // Skips unknown characters. - uint8_t data[] = "z12b"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("\x12\xb0", parser.ReadHexString()); - EXPECT_EQ(4, parser.SavePos()); - } - - { - // Skips unknown characters. - uint8_t data[] = "*<&*#$^&@1"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 10, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("\x10", parser.ReadHexString()); - EXPECT_EQ(10, parser.SavePos()); - } - - { - // Skips unknown characters. - uint8_t data[] = "\x80zab"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("\xab", parser.ReadHexString()); - EXPECT_EQ(4, parser.SavePos()); - } - - { - // Skips unknown characters. - uint8_t data[] = "\xffzab"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("\xab", parser.ReadHexString()); - EXPECT_EQ(4, parser.SavePos()); - } - - { - // Regular conversion. - uint8_t data[] = "1A2b>abcd"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 9, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); - EXPECT_EQ(5, parser.SavePos()); - } - - { - // Position out of bounds. - uint8_t data[] = "12ab>"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 5, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - parser.RestorePos(5); - EXPECT_EQ("", parser.ReadHexString()); - - parser.RestorePos(6); - EXPECT_EQ("", parser.ReadHexString()); - - parser.RestorePos(-1); - EXPECT_EQ("", parser.ReadHexString()); - - parser.RestorePos(std::numeric_limits<FX_FILESIZE>::max()); - EXPECT_EQ("", parser.ReadHexString()); - - // Check string still parses when set to 0. - parser.RestorePos(0); - EXPECT_EQ("\x12\xab", parser.ReadHexString()); - } - - { - // Missing ending >. - uint8_t data[] = "1A2b"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); - EXPECT_EQ(4, parser.SavePos()); - } - - { - // Missing ending >. - uint8_t data[] = "12abz"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 5, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("\x12\xab", parser.ReadHexString()); - EXPECT_EQ(5, parser.SavePos()); - } - - { - // Uneven number of bytes. - uint8_t data[] = "1A2>asdf"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 8, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("\x1a\x20", parser.ReadHexString()); - EXPECT_EQ(4, parser.SavePos()); - } - - { - // Uneven number of bytes. - uint8_t data[] = "1A2zasdf"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 8, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("\x1a\x2a\xdf", parser.ReadHexString()); - EXPECT_EQ(8, parser.SavePos()); - } - - { - // Just ending character. - uint8_t data[] = ">"; - ScopedFileStream stream(FX_CreateMemoryStream(data, 1, FALSE)); - - CPDF_SyntaxParser parser; - parser.InitParser(stream.get(), 0); - EXPECT_EQ("", parser.ReadHexString()); - EXPECT_EQ(1, parser.SavePos()); - } -} - -TEST(fpdf_parser_parser, RebuildCrossRefCorrectly) { +TEST(cpdf_parser, RebuildCrossRefCorrectly) { CPDF_TestParser parser; std::string test_file; ASSERT_TRUE(PathService::GetTestFilePath("parser_rebuildxref_correct.pdf", @@ -248,7 +89,7 @@ TEST(fpdf_parser_parser, RebuildCrossRefCorrectly) { EXPECT_EQ(versions[i], parser.m_ObjectInfo[i].gennum); } -TEST(fpdf_parser_parser, RebuildCrossRefFailed) { +TEST(cpdf_parser, RebuildCrossRefFailed) { CPDF_TestParser parser; std::string test_file; ASSERT_TRUE(PathService::GetTestFilePath( @@ -258,7 +99,7 @@ TEST(fpdf_parser_parser, RebuildCrossRefFailed) { ASSERT_FALSE(parser.RebuildCrossRef()); } -TEST(fpdf_parser_parser, LoadCrossRefV4) { +TEST(cpdf_parser, LoadCrossRefV4) { { const unsigned char xref_table[] = "xref \n" diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_simple_parser_unittest.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_simple_parser_unittest.cpp index f95838d91f..bfcb0afc7f 100644 --- a/core/src/fpdfapi/fpdf_parser/cpdf_simple_parser_unittest.cpp +++ b/core/src/fpdfapi/fpdf_parser/cpdf_simple_parser_unittest.cpp @@ -6,7 +6,7 @@ #include <string> -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fxcrt/fx_basic.h" #include "core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/test_support.h" diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_standard_crypto_handler.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_standard_crypto_handler.cpp index d7a6fd59fe..b656572cff 100644 --- a/core/src/fpdfapi/fpdf_parser/cpdf_standard_crypto_handler.cpp +++ b/core/src/fpdfapi/fpdf_parser/cpdf_standard_crypto_handler.cpp @@ -8,7 +8,6 @@ #include <time.h> -#include "core/include/fpdfapi/fpdf_parser.h" #include "core/include/fpdfapi/cpdf_parser.h" #include "core/include/fpdfapi/cpdf_simple_parser.h" #include "core/include/fpdfapi/ipdf_security_handler.h" diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp index 60d6ba47dd..a89b2fb119 100644 --- a/core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp +++ b/core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp @@ -10,7 +10,7 @@ #include "core/include/fdrm/fx_crypt.h" #include "core/include/fpdfapi/cpdf_parser.h" -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/fpdf_objects.h" #include "core/src/fpdfapi/fpdf_parser/cpdf_standard_crypto_handler.h" namespace { diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp index f635e02e3a..e5b782ca1c 100644 --- a/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp +++ b/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp @@ -9,7 +9,8 @@ #include <vector> #include "core/include/fpdfapi/fpdf_module.h" -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/fpdf_objects.h" +#include "core/include/fpdfapi/fpdf_parser_decode.h" #include "core/include/fpdfapi/ipdf_crypto_handler.h" #include "core/include/fxcrt/fx_ext.h" #include "core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.h" @@ -468,7 +469,7 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList, // Only when this is a signature dictionary and has contents, we reset the // contents to the un-decrypted form. - if (IsSignatureDict(pDict.get()) && dwSignValuePos) { + if (pDict->IsSignatureDict() && dwSignValuePos) { CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos); m_Pos = dwSignValuePos; pDict->SetAt("Contents", GetObject(pObjList, objnum, gennum, false)); diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h b/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h index c259efb1ee..f8794bcb7f 100644 --- a/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h +++ b/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h @@ -58,7 +58,7 @@ class CPDF_SyntaxParser { private: friend class CPDF_Parser; friend class CPDF_DataAvail; - friend class fpdf_parser_parser_ReadHexString_Test; + friend class cpdf_syntax_parser_ReadHexString_Test; static const int kParserMaxRecursionDepth = 64; static int s_CurrentRecursionDepth; diff --git a/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser_unittest.cpp b/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser_unittest.cpp new file mode 100644 index 0000000000..b03b1af450 --- /dev/null +++ b/core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser_unittest.cpp @@ -0,0 +1,171 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <limits> +#include <string> + +#include "core/include/fpdfapi/cpdf_parser.h" +#include "core/include/fxcrt/fx_ext.h" +#include "core/include/fxcrt/fx_stream.h" +#include "core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/utils/path_service.h" + +TEST(cpdf_syntax_parser, ReadHexString) { + { + // Empty string. + uint8_t data[] = ""; + ScopedFileStream stream(FX_CreateMemoryStream(data, 0, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("", parser.ReadHexString()); + EXPECT_EQ(0, parser.SavePos()); + } + + { + // Blank string. + uint8_t data[] = " "; + ScopedFileStream stream(FX_CreateMemoryStream(data, 2, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("", parser.ReadHexString()); + EXPECT_EQ(2, parser.SavePos()); + } + + { + // Skips unknown characters. + uint8_t data[] = "z12b"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("\x12\xb0", parser.ReadHexString()); + EXPECT_EQ(4, parser.SavePos()); + } + + { + // Skips unknown characters. + uint8_t data[] = "*<&*#$^&@1"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 10, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("\x10", parser.ReadHexString()); + EXPECT_EQ(10, parser.SavePos()); + } + + { + // Skips unknown characters. + uint8_t data[] = "\x80zab"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("\xab", parser.ReadHexString()); + EXPECT_EQ(4, parser.SavePos()); + } + + { + // Skips unknown characters. + uint8_t data[] = "\xffzab"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("\xab", parser.ReadHexString()); + EXPECT_EQ(4, parser.SavePos()); + } + + { + // Regular conversion. + uint8_t data[] = "1A2b>abcd"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 9, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); + EXPECT_EQ(5, parser.SavePos()); + } + + { + // Position out of bounds. + uint8_t data[] = "12ab>"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 5, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + parser.RestorePos(5); + EXPECT_EQ("", parser.ReadHexString()); + + parser.RestorePos(6); + EXPECT_EQ("", parser.ReadHexString()); + + parser.RestorePos(-1); + EXPECT_EQ("", parser.ReadHexString()); + + parser.RestorePos(std::numeric_limits<FX_FILESIZE>::max()); + EXPECT_EQ("", parser.ReadHexString()); + + // Check string still parses when set to 0. + parser.RestorePos(0); + EXPECT_EQ("\x12\xab", parser.ReadHexString()); + } + + { + // Missing ending >. + uint8_t data[] = "1A2b"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); + EXPECT_EQ(4, parser.SavePos()); + } + + { + // Missing ending >. + uint8_t data[] = "12abz"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 5, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("\x12\xab", parser.ReadHexString()); + EXPECT_EQ(5, parser.SavePos()); + } + + { + // Uneven number of bytes. + uint8_t data[] = "1A2>asdf"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 8, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("\x1a\x20", parser.ReadHexString()); + EXPECT_EQ(4, parser.SavePos()); + } + + { + // Uneven number of bytes. + uint8_t data[] = "1A2zasdf"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 8, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("\x1a\x2a\xdf", parser.ReadHexString()); + EXPECT_EQ(8, parser.SavePos()); + } + + { + // Just ending character. + uint8_t data[] = ">"; + ScopedFileStream stream(FX_CreateMemoryStream(data, 1, FALSE)); + + CPDF_SyntaxParser parser; + parser.InitParser(stream.get(), 0); + EXPECT_EQ("", parser.ReadHexString()); + EXPECT_EQ(1, parser.SavePos()); + } +} diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp index 473ea76e76..7a38209979 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp @@ -4,12 +4,13 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#include <limits.h> +#include "core/include/fpdfapi/fpdf_parser_decode.h" +#include <limits.h> #include <vector> #include "core/include/fpdfapi/fpdf_module.h" -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/fpdf_objects.h" #include "core/include/fxcodec/fx_codec.h" #include "core/include/fxcrt/fx_ext.h" #include "core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.h" diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp index 7ed82fdfb6..2412f4310c 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp @@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "core/include/fpdfapi/fpdf_parser_decode.h" + #include <cstring> #include <string> -#include "core/include/fpdfapi/fpdf_parser.h" #include "core/include/fxcrt/fx_basic.h" #include "testing/embedder_test.h" #include "testing/fx_string_testhelpers.h" diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_unittest.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_unittest.cpp index 8c1d971255..e00759da7a 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_unittest.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_unittest.cpp @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/fpdf_parser_decode.h" + #include "testing/gtest/include/gtest/gtest.h" #include "testing/test_support.h" diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp index 28c35c899e..05d85e6398 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp @@ -9,7 +9,7 @@ #include <algorithm> #include "core/include/fpdfapi/cpdf_parser.h" -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/fpdf_parser_decode.h" #include "core/include/fxcrt/fx_string.h" #include "third_party/base/stl_util.h" @@ -669,6 +669,13 @@ FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteStringC& key) const { return pdfium::ContainsKey(m_Map, key); } +bool CPDF_Dictionary::IsSignatureDict() const { + CPDF_Object* pType = GetElementValue("Type"); + if (!pType) + pType = GetElementValue("FT"); + return pType && pType->GetString() == "Sig"; +} + void CPDF_Dictionary::SetAt(const CFX_ByteStringC& key, CPDF_Object* pObj) { ASSERT(IsDictionary()); // Avoid 2 constructions of CFX_ByteString. diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp index 3bf3f58432..0c948c5062 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp @@ -6,7 +6,8 @@ #include "core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.h" -#include "core/include/fpdfapi/fpdf_parser.h" +#include "core/include/fpdfapi/fpdf_objects.h" +#include "core/include/fpdfapi/fpdf_parser_decode.h" #include "core/include/fxcrt/fx_ext.h" // Indexed by 8-bit character code, contains either: diff --git a/core/src/fpdfdoc/doc_form.cpp b/core/src/fpdfdoc/doc_form.cpp index 7469cfd28f..716d283450 100644 --- a/core/src/fpdfdoc/doc_form.cpp +++ b/core/src/fpdfdoc/doc_form.cpp @@ -7,6 +7,7 @@ #include <vector> #include "core/include/fpdfapi/cpdf_document.h" +#include "core/include/fpdfapi/cfdf_document.h" #include "core/include/fpdfdoc/fpdf_doc.h" #include "core/src/fpdfdoc/doc_utils.h" #include "third_party/base/stl_util.h" diff --git a/core/src/fpdfdoc/doc_tagged.cpp b/core/src/fpdfdoc/doc_tagged.cpp index 2d0677efa4..a671875688 100644 --- a/core/src/fpdfdoc/doc_tagged.cpp +++ b/core/src/fpdfdoc/doc_tagged.cpp @@ -8,7 +8,6 @@ #include "core/include/fpdfapi/cpdf_document.h" #include "core/include/fpdfapi/fpdf_page.h" -#include "core/include/fpdfapi/fpdf_parser.h" #include "core/include/fpdfdoc/fpdf_tagged.h" #include "core/src/fpdfdoc/doc_utils.h" #include "core/src/fpdfdoc/tagged_int.h" |