OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "../../../include/fpdfapi/fpdf_module.h" | 11 #include "../../../include/fpdfapi/fpdf_module.h" |
12 #include "../../../include/fpdfapi/fpdf_page.h" | 12 #include "../../../include/fpdfapi/fpdf_page.h" |
13 #include "../../../include/fpdfapi/fpdf_parser.h" | 13 #include "../../../include/fpdfapi/fpdf_parser.h" |
14 #include "../../../include/fxcrt/fx_safe_types.h" | 14 #include "../../../include/fxcrt/fx_safe_types.h" |
15 #include "../fpdf_page/pageint.h" | 15 #include "../fpdf_page/pageint.h" |
| 16 #include "parser_int.h" |
16 | 17 |
17 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) { | 18 FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) { |
18 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); | 19 CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); |
19 if (!pType) { | 20 if (!pType) { |
20 pType = pDict->GetElementValue(FX_BSTRC("FT")); | 21 pType = pDict->GetElementValue(FX_BSTRC("FT")); |
21 if (!pType) { | 22 if (!pType) { |
22 return FALSE; | 23 return FALSE; |
23 } | 24 } |
24 } | 25 } |
25 if (pType->GetString() == FX_BSTRC("Sig")) { | 26 if (pType->GetString() == FX_BSTRC("Sig")) { |
(...skipping 2778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2804 } | 2805 } |
2805 buffer[offset++] = ch; | 2806 buffer[offset++] = ch; |
2806 if (offset == size) { | 2807 if (offset == size) { |
2807 break; | 2808 break; |
2808 } | 2809 } |
2809 } | 2810 } |
2810 } | 2811 } |
2811 | 2812 |
2812 class CPDF_DataAvail final : public IPDF_DataAvail { | 2813 class CPDF_DataAvail final : public IPDF_DataAvail { |
2813 public: | 2814 public: |
2814 CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); | 2815 CPDF_DataAvail(IFX_FileAvail* pFileAvail, |
| 2816 IFX_FileRead* pFileRead, |
| 2817 FX_BOOL bSupportHintTable); |
2815 ~CPDF_DataAvail() override; | 2818 ~CPDF_DataAvail() override; |
2816 | 2819 |
2817 virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; | 2820 virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; |
2818 | 2821 |
2819 virtual void SetDocument(CPDF_Document* pDoc) override; | 2822 virtual void SetDocument(CPDF_Document* pDoc) override; |
2820 | 2823 |
2821 virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; | 2824 virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; |
2822 | 2825 |
2823 virtual int32_t IsFormAvail(IFX_DownloadHints* pHints) override; | 2826 virtual int32_t IsFormAvail(IFX_DownloadHints* pHints) override; |
2824 | 2827 |
2825 virtual int32_t IsLinearizedPDF() override; | 2828 virtual int32_t IsLinearizedPDF() override; |
2826 | 2829 |
2827 virtual FX_BOOL IsLinearized() override { return m_bLinearized; } | 2830 virtual FX_BOOL IsLinearized() override { return m_bLinearized; } |
2828 | 2831 |
2829 virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, | 2832 virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, |
2830 FX_DWORD* pSize) override; | 2833 FX_DWORD* pSize) override; |
| 2834 int GetPageCount() const; |
| 2835 CPDF_Dictionary* GetPage(int index); |
| 2836 |
| 2837 friend class CPDF_HintTables; |
2831 | 2838 |
2832 protected: | 2839 protected: |
2833 static const int kMaxDataAvailRecursionDepth = 64; | 2840 static const int kMaxDataAvailRecursionDepth = 64; |
2834 static int s_CurrentDataAvailRecursionDepth; | 2841 static int s_CurrentDataAvailRecursionDepth; |
2835 | 2842 |
2836 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); | 2843 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); |
2837 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, | 2844 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, |
2838 FX_BOOL bParsePage, | 2845 FX_BOOL bParsePage, |
2839 IFX_DownloadHints* pHints, | 2846 IFX_DownloadHints* pHints, |
2840 CFX_PtrArray& ret_array); | 2847 CFX_PtrArray& ret_array); |
2841 FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints); | 2848 FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints); |
2842 FX_BOOL CheckHeader(IFX_DownloadHints* pHints); | 2849 FX_BOOL CheckHeader(IFX_DownloadHints* pHints); |
2843 FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints); | 2850 FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints); |
| 2851 FX_BOOL CheckHintTables(IFX_DownloadHints* pHints); |
2844 FX_BOOL CheckEnd(IFX_DownloadHints* pHints); | 2852 FX_BOOL CheckEnd(IFX_DownloadHints* pHints); |
2845 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); | 2853 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); |
2846 FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints); | 2854 FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints); |
2847 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); | 2855 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); |
2848 FX_BOOL CheckRoot(IFX_DownloadHints* pHints); | 2856 FX_BOOL CheckRoot(IFX_DownloadHints* pHints); |
2849 FX_BOOL CheckInfo(IFX_DownloadHints* pHints); | 2857 FX_BOOL CheckInfo(IFX_DownloadHints* pHints); |
2850 FX_BOOL CheckPages(IFX_DownloadHints* pHints); | 2858 FX_BOOL CheckPages(IFX_DownloadHints* pHints); |
2851 FX_BOOL CheckPage(IFX_DownloadHints* pHints); | 2859 FX_BOOL CheckPage(IFX_DownloadHints* pHints); |
2852 FX_BOOL CheckResources(IFX_DownloadHints* pHints); | 2860 FX_BOOL CheckResources(IFX_DownloadHints* pHints); |
2853 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); | 2861 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); |
2854 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); | 2862 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); |
2855 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); | 2863 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); |
2856 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); | 2864 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); |
2857 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); | 2865 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); |
2858 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints); | 2866 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints); |
2859 | 2867 |
2860 int32_t CheckCrossRefStream(IFX_DownloadHints* pHints, | 2868 int32_t CheckCrossRefStream(IFX_DownloadHints* pHints, |
2861 FX_FILESIZE& xref_offset); | 2869 FX_FILESIZE& xref_offset); |
2862 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); | 2870 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); |
2863 void SetStartOffset(FX_FILESIZE dwOffset); | 2871 void SetStartOffset(FX_FILESIZE dwOffset); |
2864 FX_BOOL GetNextToken(CFX_ByteString& token); | 2872 FX_BOOL GetNextToken(CFX_ByteString& token); |
2865 FX_BOOL GetNextChar(uint8_t& ch); | 2873 FX_BOOL GetNextChar(uint8_t& ch); |
2866 CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum); | 2874 CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos, |
| 2875 FX_DWORD objnum, |
| 2876 CPDF_IndirectObjects* pObjList = NULL); |
2867 CPDF_Object* GetObject(FX_DWORD objnum, | 2877 CPDF_Object* GetObject(FX_DWORD objnum, |
2868 IFX_DownloadHints* pHints, | 2878 IFX_DownloadHints* pHints, |
2869 FX_BOOL* pExistInFile); | 2879 FX_BOOL* pExistInFile); |
2870 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); | 2880 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); |
2871 FX_BOOL PreparePageItem(); | 2881 FX_BOOL PreparePageItem(); |
2872 FX_BOOL LoadPages(IFX_DownloadHints* pHints); | 2882 FX_BOOL LoadPages(IFX_DownloadHints* pHints); |
2873 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); | 2883 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); |
2874 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); | 2884 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); |
2875 FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); | 2885 FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); |
2876 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); | 2886 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); |
(...skipping 10 matching lines...) Expand all Loading... |
2887 IFX_DownloadHints* pHints); | 2897 IFX_DownloadHints* pHints); |
2888 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, | 2898 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, |
2889 CPDF_PageNode* pPageNode, | 2899 CPDF_PageNode* pPageNode, |
2890 IFX_DownloadHints* pHints); | 2900 IFX_DownloadHints* pHints); |
2891 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, | 2901 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, |
2892 CPDF_PageNode* pPageNode, | 2902 CPDF_PageNode* pPageNode, |
2893 IFX_DownloadHints* pHints); | 2903 IFX_DownloadHints* pHints); |
2894 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); | 2904 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); |
2895 FX_BOOL IsFirstCheck(int iPage); | 2905 FX_BOOL IsFirstCheck(int iPage); |
2896 void ResetFirstCheck(int iPage); | 2906 void ResetFirstCheck(int iPage); |
| 2907 FX_BOOL IsDataAvail(FX_FILESIZE offset, |
| 2908 FX_DWORD size, |
| 2909 IFX_DownloadHints* pHints); |
2897 | 2910 |
2898 CPDF_Parser m_parser; | 2911 CPDF_Parser m_parser; |
2899 | 2912 |
2900 CPDF_SyntaxParser m_syntaxParser; | 2913 CPDF_SyntaxParser m_syntaxParser; |
2901 | 2914 |
2902 CPDF_Object* m_pRoot; | 2915 CPDF_Object* m_pRoot; |
2903 | 2916 |
2904 FX_DWORD m_dwRootObjNum; | 2917 FX_DWORD m_dwRootObjNum; |
2905 | 2918 |
2906 FX_DWORD m_dwInfoObjNum; | 2919 FX_DWORD m_dwInfoObjNum; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3000 FX_FILESIZE m_dwPrevXRefOffset; | 3013 FX_FILESIZE m_dwPrevXRefOffset; |
3001 | 3014 |
3002 FX_BOOL m_bTotalLoadPageTree; | 3015 FX_BOOL m_bTotalLoadPageTree; |
3003 | 3016 |
3004 FX_BOOL m_bCurPageDictLoadOK; | 3017 FX_BOOL m_bCurPageDictLoadOK; |
3005 | 3018 |
3006 CPDF_PageNode m_pageNodes; | 3019 CPDF_PageNode m_pageNodes; |
3007 | 3020 |
3008 std::set<FX_DWORD> m_pageMapCheckState; | 3021 std::set<FX_DWORD> m_pageMapCheckState; |
3009 std::set<FX_DWORD> m_pagesLoadState; | 3022 std::set<FX_DWORD> m_pagesLoadState; |
| 3023 |
| 3024 nonstd::unique_ptr<CPDF_HintTables> m_pHintTables; |
| 3025 FX_BOOL m_bSupportHintTable; |
3010 }; | 3026 }; |
3011 | 3027 |
3012 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, | 3028 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, |
3013 IFX_FileRead* pFileRead) | 3029 IFX_FileRead* pFileRead) |
3014 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} | 3030 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} |
3015 | 3031 |
3016 // static | 3032 // static |
3017 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, | 3033 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, |
3018 IFX_FileRead* pFileRead) { | 3034 IFX_FileRead* pFileRead) { |
3019 return new CPDF_DataAvail(pFileAvail, pFileRead); | 3035 return new CPDF_DataAvail(pFileAvail, pFileRead, FALSE); |
3020 } | 3036 } |
3021 | 3037 |
3022 // static | 3038 // static |
3023 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; | 3039 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; |
3024 | 3040 |
3025 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, | 3041 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, |
3026 IFX_FileRead* pFileRead) | 3042 IFX_FileRead* pFileRead, |
| 3043 FX_BOOL bSupportHintTable) |
3027 : IPDF_DataAvail(pFileAvail, pFileRead) { | 3044 : IPDF_DataAvail(pFileAvail, pFileRead) { |
3028 m_Pos = 0; | 3045 m_Pos = 0; |
3029 m_dwFileLen = 0; | 3046 m_dwFileLen = 0; |
3030 if (m_pFileRead) { | 3047 if (m_pFileRead) { |
3031 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); | 3048 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); |
3032 } | 3049 } |
3033 m_dwCurrentOffset = 0; | 3050 m_dwCurrentOffset = 0; |
3034 m_WordSize = 0; | 3051 m_WordSize = 0; |
3035 m_dwXRefOffset = 0; | 3052 m_dwXRefOffset = 0; |
3036 m_bufferOffset = 0; | 3053 m_bufferOffset = 0; |
(...skipping 25 matching lines...) Expand all Loading... |
3062 m_pTrailer = NULL; | 3079 m_pTrailer = NULL; |
3063 m_pCurrentParser = NULL; | 3080 m_pCurrentParser = NULL; |
3064 m_pAcroForm = NULL; | 3081 m_pAcroForm = NULL; |
3065 m_pPageDict = NULL; | 3082 m_pPageDict = NULL; |
3066 m_pPageResource = NULL; | 3083 m_pPageResource = NULL; |
3067 m_docStatus = PDF_DATAAVAIL_HEADER; | 3084 m_docStatus = PDF_DATAAVAIL_HEADER; |
3068 m_parser.m_bOwnFileRead = FALSE; | 3085 m_parser.m_bOwnFileRead = FALSE; |
3069 m_bTotalLoadPageTree = FALSE; | 3086 m_bTotalLoadPageTree = FALSE; |
3070 m_bCurPageDictLoadOK = FALSE; | 3087 m_bCurPageDictLoadOK = FALSE; |
3071 m_bLinearedDataOK = FALSE; | 3088 m_bLinearedDataOK = FALSE; |
| 3089 m_bSupportHintTable = bSupportHintTable; |
3072 } | 3090 } |
3073 CPDF_DataAvail::~CPDF_DataAvail() { | 3091 CPDF_DataAvail::~CPDF_DataAvail() { |
3074 if (m_pLinearized) { | 3092 if (m_pLinearized) { |
3075 m_pLinearized->Release(); | 3093 m_pLinearized->Release(); |
3076 } | 3094 } |
3077 if (m_pRoot) { | 3095 if (m_pRoot) { |
3078 m_pRoot->Release(); | 3096 m_pRoot->Release(); |
3079 } | 3097 } |
3080 if (m_pTrailer) { | 3098 if (m_pTrailer) { |
3081 m_pTrailer->Release(); | 3099 m_pTrailer->Release(); |
3082 } | 3100 } |
3083 int32_t i = 0; | 3101 |
3084 int32_t iSize = m_arrayAcroforms.GetSize(); | 3102 int32_t iSize = m_arrayAcroforms.GetSize(); |
3085 for (i = 0; i < iSize; ++i) { | 3103 for (int i = 0; i < iSize; ++i) { |
3086 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release(); | 3104 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release(); |
3087 } | 3105 } |
3088 } | 3106 } |
3089 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { | 3107 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { |
3090 m_pDocument = pDoc; | 3108 m_pDocument = pDoc; |
3091 } | 3109 } |
3092 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { | 3110 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { |
3093 CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser()); | 3111 CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser()); |
3094 if (pParser == NULL) { | 3112 if (pParser == NULL) { |
3095 return 0; | 3113 return 0; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3157 value = pDict->GetNextElement(pos, key); | 3175 value = pDict->GetNextElement(pos, key); |
3158 if (key != "Parent") { | 3176 if (key != "Parent") { |
3159 new_obj_array.Add(value); | 3177 new_obj_array.Add(value); |
3160 } | 3178 } |
3161 } | 3179 } |
3162 } break; | 3180 } break; |
3163 case PDFOBJ_REFERENCE: { | 3181 case PDFOBJ_REFERENCE: { |
3164 CPDF_Reference* pRef = (CPDF_Reference*)pObj; | 3182 CPDF_Reference* pRef = (CPDF_Reference*)pObj; |
3165 FX_DWORD dwNum = pRef->GetRefObjNum(); | 3183 FX_DWORD dwNum = pRef->GetRefObjNum(); |
3166 FX_FILESIZE offset; | 3184 FX_FILESIZE offset; |
3167 FX_DWORD original_size = GetObjectSize(dwNum, offset); | 3185 FX_DWORD size = GetObjectSize(dwNum, offset); |
3168 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; | 3186 if (size == 0 || offset < 0 || offset >= m_dwFileLen) { |
3169 if (size.ValueOrDefault(0) == 0 || offset < 0 || | |
3170 offset >= m_dwFileLen) { | |
3171 break; | 3187 break; |
3172 } | 3188 } |
3173 | 3189 if (!IsDataAvail(offset, size, pHints)) { |
3174 size += offset; | |
3175 size += 512; | |
3176 if (!size.IsValid()) { | |
3177 break; | |
3178 } | |
3179 if (size.ValueOrDie() > m_dwFileLen) { | |
3180 size = m_dwFileLen - offset; | |
3181 } else { | |
3182 size = original_size + 512; | |
3183 } | |
3184 if (!size.IsValid()) { | |
3185 break; | |
3186 } | |
3187 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { | |
3188 pHints->AddSegment(offset, size.ValueOrDie()); | |
3189 ret_array.Add(pObj); | 3190 ret_array.Add(pObj); |
3190 count++; | 3191 count++; |
3191 } else if (!m_objnum_array.Find(dwNum)) { | 3192 } else if (!m_objnum_array.Find(dwNum)) { |
3192 m_objnum_array.AddObjNum(dwNum); | 3193 m_objnum_array.AddObjNum(dwNum); |
3193 CPDF_Object* pReferred = | 3194 CPDF_Object* pReferred = |
3194 m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL); | 3195 m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL); |
3195 if (pReferred) { | 3196 if (pReferred) { |
3196 new_obj_array.Add(pReferred); | 3197 new_obj_array.Add(pReferred); |
3197 } | 3198 } |
3198 } | 3199 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3278 m_docStatus = PDF_DATAAVAIL_PAGETREE; | 3279 m_docStatus = PDF_DATAAVAIL_PAGETREE; |
3279 return TRUE; | 3280 return TRUE; |
3280 } | 3281 } |
3281 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { | 3282 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { |
3282 switch (m_docStatus) { | 3283 switch (m_docStatus) { |
3283 case PDF_DATAAVAIL_HEADER: | 3284 case PDF_DATAAVAIL_HEADER: |
3284 return CheckHeader(pHints); | 3285 return CheckHeader(pHints); |
3285 case PDF_DATAAVAIL_FIRSTPAGE: | 3286 case PDF_DATAAVAIL_FIRSTPAGE: |
3286 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: | 3287 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: |
3287 return CheckFirstPage(pHints); | 3288 return CheckFirstPage(pHints); |
| 3289 case PDF_DATAAVAIL_HINTTABLE: |
| 3290 return CheckHintTables(pHints); |
3288 case PDF_DATAAVAIL_END: | 3291 case PDF_DATAAVAIL_END: |
3289 return CheckEnd(pHints); | 3292 return CheckEnd(pHints); |
3290 case PDF_DATAAVAIL_CROSSREF: | 3293 case PDF_DATAAVAIL_CROSSREF: |
3291 return CheckCrossRef(pHints); | 3294 return CheckCrossRef(pHints); |
3292 case PDF_DATAAVAIL_CROSSREF_ITEM: | 3295 case PDF_DATAAVAIL_CROSSREF_ITEM: |
3293 return CheckCrossRefItem(pHints); | 3296 return CheckCrossRefItem(pHints); |
3294 case PDF_DATAAVAIL_CROSSREF_STREAM: | 3297 case PDF_DATAAVAIL_CROSSREF_STREAM: |
3295 return CheckAllCrossRefStream(pHints); | 3298 return CheckAllCrossRefStream(pHints); |
3296 case PDF_DATAAVAIL_TRAILER: | 3299 case PDF_DATAAVAIL_TRAILER: |
3297 return CheckTrailer(pHints); | 3300 return CheckTrailer(pHints); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3362 _CompareFileSize); | 3365 _CompareFileSize); |
3363 m_dwRootObjNum = m_parser.GetRootObjNum(); | 3366 m_dwRootObjNum = m_parser.GetRootObjNum(); |
3364 m_dwInfoObjNum = m_parser.GetInfoObjNum(); | 3367 m_dwInfoObjNum = m_parser.GetInfoObjNum(); |
3365 m_pCurrentParser = &m_parser; | 3368 m_pCurrentParser = &m_parser; |
3366 m_docStatus = PDF_DATAAVAIL_ROOT; | 3369 m_docStatus = PDF_DATAAVAIL_ROOT; |
3367 return TRUE; | 3370 return TRUE; |
3368 } | 3371 } |
3369 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, | 3372 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, |
3370 IFX_DownloadHints* pHints, | 3373 IFX_DownloadHints* pHints, |
3371 FX_BOOL* pExistInFile) { | 3374 FX_BOOL* pExistInFile) { |
3372 CPDF_Object* pRet = NULL; | 3375 CPDF_Object* pRet = nullptr; |
3373 FX_DWORD original_size = 0; | 3376 FX_DWORD size = 0; |
3374 FX_FILESIZE offset = 0; | 3377 FX_FILESIZE offset = 0; |
3375 CPDF_Parser* pParser = NULL; | 3378 CPDF_Parser* pParser = nullptr; |
3376 | 3379 if (pExistInFile) |
3377 if (pExistInFile) { | |
3378 *pExistInFile = TRUE; | 3380 *pExistInFile = TRUE; |
3379 } | |
3380 | 3381 |
3381 if (m_pDocument == NULL) { | 3382 if (m_pDocument == NULL) { |
3382 original_size = (FX_DWORD)m_parser.GetObjectSize(objnum); | 3383 size = (FX_DWORD)m_parser.GetObjectSize(objnum); |
3383 offset = m_parser.GetObjectOffset(objnum); | 3384 offset = m_parser.GetObjectOffset(objnum); |
3384 pParser = &m_parser; | 3385 pParser = &m_parser; |
3385 } else { | 3386 } else { |
3386 original_size = GetObjectSize(objnum, offset); | 3387 size = GetObjectSize(objnum, offset); |
3387 pParser = (CPDF_Parser*)(m_pDocument->GetParser()); | 3388 pParser = (CPDF_Parser*)(m_pDocument->GetParser()); |
3388 } | 3389 } |
3389 | 3390 if (!IsDataAvail(offset, size, pHints)) { |
3390 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; | 3391 return nullptr; |
3391 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) { | |
3392 if (pExistInFile) | |
3393 *pExistInFile = FALSE; | |
3394 | |
3395 return NULL; | |
3396 } | 3392 } |
3397 | |
3398 size += offset; | |
3399 size += 512; | |
3400 if (!size.IsValid()) { | |
3401 return NULL; | |
3402 } | |
3403 | |
3404 if (size.ValueOrDie() > m_dwFileLen) { | |
3405 size = m_dwFileLen - offset; | |
3406 } else { | |
3407 size = original_size + 512; | |
3408 } | |
3409 | |
3410 if (!size.IsValid()) { | |
3411 return NULL; | |
3412 } | |
3413 | |
3414 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { | |
3415 pHints->AddSegment(offset, size.ValueOrDie()); | |
3416 return NULL; | |
3417 } | |
3418 | |
3419 if (pParser) { | 3393 if (pParser) { |
3420 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); | 3394 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); |
3421 } | 3395 } |
3422 | 3396 |
3423 if (!pRet && pExistInFile) { | 3397 if (!pRet && pExistInFile) { |
3424 *pExistInFile = FALSE; | 3398 *pExistInFile = FALSE; |
3425 } | 3399 } |
3426 | 3400 |
3427 return pRet; | 3401 return pRet; |
3428 } | 3402 } |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3709 FX_FILESIZE offset = m_dwLastXRefOffset; | 3683 FX_FILESIZE offset = m_dwLastXRefOffset; |
3710 if (dwSize < 512 && dwFileLen > 512) { | 3684 if (dwSize < 512 && dwFileLen > 512) { |
3711 dwSize = 512; | 3685 dwSize = 512; |
3712 offset = dwFileLen - 512; | 3686 offset = dwFileLen - 512; |
3713 } | 3687 } |
3714 pHints->AddSegment(offset, dwSize); | 3688 pHints->AddSegment(offset, dwSize); |
3715 } | 3689 } |
3716 } else { | 3690 } else { |
3717 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; | 3691 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; |
3718 } | 3692 } |
3719 if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { | 3693 if (bNeedDownLoad || m_docStatus != PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { |
| 3694 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; |
| 3695 return FALSE; |
| 3696 } |
| 3697 m_docStatus = |
| 3698 m_bSupportHintTable ? PDF_DATAAVAIL_HINTTABLE : PDF_DATAAVAIL_DONE; |
| 3699 return TRUE; |
| 3700 } |
| 3701 FX_BOOL CPDF_DataAvail::IsDataAvail(FX_FILESIZE offset, |
| 3702 FX_DWORD size, |
| 3703 IFX_DownloadHints* pHints) { |
| 3704 if (!pHints || offset > m_dwFileLen) |
| 3705 return TRUE; |
| 3706 FX_SAFE_DWORD safeSize = pdfium::base::checked_cast<FX_DWORD>(offset); |
| 3707 safeSize += size; |
| 3708 safeSize += 512; |
| 3709 if (!safeSize.IsValid() || safeSize.ValueOrDie() > m_dwFileLen) |
| 3710 size = m_dwFileLen - offset; |
| 3711 else |
| 3712 size += 512; |
| 3713 if (!m_pFileAvail->IsDataAvail(offset, size)) { |
| 3714 pHints->AddSegment(offset, size); |
| 3715 return FALSE; |
| 3716 } |
| 3717 return TRUE; |
| 3718 } |
| 3719 FX_BOOL CPDF_DataAvail::CheckHintTables(IFX_DownloadHints* pHints) { |
| 3720 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); |
| 3721 if (!pDict || !pHints) { |
| 3722 return TRUE; |
| 3723 } |
| 3724 if (!pDict->KeyExist(FX_BSTRC("H")) || !pDict->KeyExist(FX_BSTRC("O")) || |
| 3725 !pDict->KeyExist(FX_BSTRC("N"))) { |
3720 m_docStatus = PDF_DATAAVAIL_DONE; | 3726 m_docStatus = PDF_DATAAVAIL_DONE; |
3721 return TRUE; | 3727 return TRUE; |
3722 } | 3728 } |
3723 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; | 3729 int nPageCount = pDict->GetElementValue(FX_BSTRC("N"))->GetInteger(); |
3724 return FALSE; | 3730 if (nPageCount <= 1) { |
| 3731 m_docStatus = PDF_DATAAVAIL_DONE; |
| 3732 return TRUE; |
| 3733 } |
| 3734 CPDF_Array* pHintStreamRange = pDict->GetArray(FX_BSTRC("H")); |
| 3735 FX_FILESIZE szHSStart = |
| 3736 pHintStreamRange->GetElementValue(0) |
| 3737 ? pHintStreamRange->GetElementValue(0)->GetInteger() |
| 3738 : 0; |
| 3739 FX_FILESIZE szHSLength = |
| 3740 pHintStreamRange->GetElementValue(1) |
| 3741 ? pHintStreamRange->GetElementValue(1)->GetInteger() |
| 3742 : 0; |
| 3743 if (szHSStart < 0 || szHSLength <= 0) { |
| 3744 m_docStatus = PDF_DATAAVAIL_DONE; |
| 3745 return TRUE; |
| 3746 } |
| 3747 if (!IsDataAvail(szHSStart, szHSLength, pHints)) { |
| 3748 return FALSE; |
| 3749 } |
| 3750 m_syntaxParser.InitParser(m_pFileRead, m_dwHeaderOffset); |
| 3751 nonstd::unique_ptr<CPDF_HintTables> pHintTables( |
| 3752 new CPDF_HintTables(this, pDict)); |
| 3753 CPDF_Stream* pHintStream = (CPDF_Stream*)ParseIndirectObjectAt(szHSStart, 0); |
| 3754 if (!pHintStream || pHintStream->GetType() != PDFOBJ_STREAM) { |
| 3755 return FALSE; |
| 3756 } |
| 3757 if (pHintTables && !pHintTables->LoadHintStream(pHintStream)) { |
| 3758 return FALSE; |
| 3759 } |
| 3760 m_pHintTables.reset(pHintTables.release()); |
| 3761 m_docStatus = PDF_DATAAVAIL_DONE; |
| 3762 return TRUE; |
3725 } | 3763 } |
3726 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, | 3764 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt( |
3727 FX_DWORD objnum) { | 3765 FX_FILESIZE pos, |
| 3766 FX_DWORD objnum, |
| 3767 CPDF_IndirectObjects* pObjList) { |
3728 FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); | 3768 FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); |
3729 m_syntaxParser.RestorePos(pos); | 3769 m_syntaxParser.RestorePos(pos); |
3730 FX_BOOL bIsNumber; | 3770 FX_BOOL bIsNumber; |
3731 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); | 3771 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); |
3732 if (!bIsNumber) { | 3772 if (!bIsNumber) { |
3733 return NULL; | 3773 return NULL; |
3734 } | 3774 } |
3735 FX_DWORD parser_objnum = FXSYS_atoi(word); | 3775 FX_DWORD parser_objnum = FXSYS_atoi(word); |
3736 if (objnum && parser_objnum != objnum) { | 3776 if (objnum && parser_objnum != objnum) { |
3737 return NULL; | 3777 return NULL; |
3738 } | 3778 } |
3739 word = m_syntaxParser.GetNextWord(bIsNumber); | 3779 word = m_syntaxParser.GetNextWord(bIsNumber); |
3740 if (!bIsNumber) { | 3780 if (!bIsNumber) { |
3741 return NULL; | 3781 return NULL; |
3742 } | 3782 } |
3743 FX_DWORD gennum = FXSYS_atoi(word); | 3783 FX_DWORD gennum = FXSYS_atoi(word); |
3744 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { | 3784 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { |
3745 m_syntaxParser.RestorePos(SavedPos); | 3785 m_syntaxParser.RestorePos(SavedPos); |
3746 return NULL; | 3786 return NULL; |
3747 } | 3787 } |
3748 CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0); | 3788 CPDF_Object* pObj = |
| 3789 m_syntaxParser.GetObject(pObjList, parser_objnum, gennum, 0); |
3749 m_syntaxParser.RestorePos(SavedPos); | 3790 m_syntaxParser.RestorePos(SavedPos); |
3750 return pObj; | 3791 return pObj; |
3751 } | 3792 } |
3752 int32_t CPDF_DataAvail::IsLinearizedPDF() { | 3793 int32_t CPDF_DataAvail::IsLinearizedPDF() { |
3753 FX_DWORD req_size = 1024; | 3794 FX_DWORD req_size = 1024; |
3754 if (!m_pFileAvail->IsDataAvail(0, req_size)) { | 3795 if (!m_pFileAvail->IsDataAvail(0, req_size)) { |
3755 return PDF_UNKNOW_LINEARIZED; | 3796 return PDF_FILE_UNKNOW; |
3756 } | 3797 } |
3757 if (!m_pFileRead) { | 3798 if (!m_pFileRead) { |
3758 return PDF_NOT_LINEARIZED; | 3799 return PDF_FILE_NOTLINEARIZED; |
3759 } | 3800 } |
3760 FX_FILESIZE dwSize = m_pFileRead->GetSize(); | 3801 FX_FILESIZE dwSize = m_pFileRead->GetSize(); |
3761 if (dwSize < (FX_FILESIZE)req_size) { | 3802 if (dwSize < (FX_FILESIZE)req_size) { |
3762 return PDF_UNKNOW_LINEARIZED; | 3803 return PDF_FILE_UNKNOW; |
3763 } | 3804 } |
3764 uint8_t buffer[1024]; | 3805 uint8_t buffer[1024]; |
3765 m_pFileRead->ReadBlock(buffer, 0, req_size); | 3806 m_pFileRead->ReadBlock(buffer, 0, req_size); |
3766 if (IsLinearizedFile(buffer, req_size)) { | 3807 if (IsLinearizedFile(buffer, req_size)) { |
3767 return PDF_IS_LINEARIZED; | 3808 return PDF_FILE_LINEARIZED; |
3768 } | 3809 } |
3769 return PDF_NOT_LINEARIZED; | 3810 return PDF_FILE_NOTLINEARIZED; |
3770 } | 3811 } |
3771 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { | 3812 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { |
3772 CFX_SmartPointer<IFX_FileStream> file( | 3813 CFX_SmartPointer<IFX_FileStream> file( |
3773 FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); | 3814 FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); |
3774 int32_t offset = GetHeaderOffset(file.Get()); | 3815 int32_t offset = GetHeaderOffset(file.Get()); |
3775 if (offset == -1) { | 3816 if (offset == -1) { |
3776 m_docStatus = PDF_DATAAVAIL_ERROR; | 3817 m_docStatus = PDF_DATAAVAIL_ERROR; |
3777 return FALSE; | 3818 return FALSE; |
3778 } | 3819 } |
3779 m_dwHeaderOffset = offset; | 3820 m_dwHeaderOffset = offset; |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4496 return TRUE; | 4537 return TRUE; |
4497 } | 4538 } |
4498 if (m_bLinearized) { | 4539 if (m_bLinearized) { |
4499 if ((FX_DWORD)iPage == m_dwFirstPageNo) { | 4540 if ((FX_DWORD)iPage == m_dwFirstPageNo) { |
4500 m_pagesLoadState.insert(iPage); | 4541 m_pagesLoadState.insert(iPage); |
4501 return TRUE; | 4542 return TRUE; |
4502 } | 4543 } |
4503 if (!CheckLinearizedData(pHints)) { | 4544 if (!CheckLinearizedData(pHints)) { |
4504 return FALSE; | 4545 return FALSE; |
4505 } | 4546 } |
| 4547 if (m_pHintTables) { |
| 4548 if (!m_pHintTables->CheckPage(iPage, pHints)) |
| 4549 return FALSE; |
| 4550 m_pagesLoadState.insert(iPage); |
| 4551 return TRUE; |
| 4552 } |
4506 if (m_bMainXRefLoadedOK) { | 4553 if (m_bMainXRefLoadedOK) { |
4507 if (m_bTotalLoadPageTree) { | 4554 if (m_bTotalLoadPageTree) { |
4508 if (!LoadPages(pHints)) { | 4555 if (!LoadPages(pHints)) { |
4509 return FALSE; | 4556 return FALSE; |
4510 } | 4557 } |
4511 } else { | 4558 } else { |
4512 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { | 4559 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { |
4513 return FALSE; | 4560 return FALSE; |
4514 } | 4561 } |
4515 } | 4562 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4616 } | 4663 } |
4617 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, | 4664 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, |
4618 FX_DWORD* pSize) { | 4665 FX_DWORD* pSize) { |
4619 if (pPos) { | 4666 if (pPos) { |
4620 *pPos = m_dwLastXRefOffset; | 4667 *pPos = m_dwLastXRefOffset; |
4621 } | 4668 } |
4622 if (pSize) { | 4669 if (pSize) { |
4623 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); | 4670 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); |
4624 } | 4671 } |
4625 } | 4672 } |
| 4673 int CPDF_DataAvail::GetPageCount() const { |
| 4674 if (!m_pDocument && !m_pLinearized) { |
| 4675 return 0; |
| 4676 } |
| 4677 if (m_pLinearized) { |
| 4678 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); |
| 4679 CPDF_Object* pObj = pDict ? pDict->GetElementValue(FX_BSTRC("N")) : nullptr; |
| 4680 return pObj ? pObj->GetInteger() : 0; |
| 4681 } |
| 4682 return m_pDocument->GetPageCount(); |
| 4683 } |
| 4684 CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) { |
| 4685 if (!m_pDocument || index < 0 || index >= this->GetPageCount()) { |
| 4686 return nullptr; |
| 4687 } |
| 4688 if (m_pLinearized) { |
| 4689 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); |
| 4690 CPDF_Object* pObj = pDict ? pDict->GetElementValue(FX_BSTRC("P")) : nullptr; |
| 4691 int pageNum = pObj ? pObj->GetInteger() : 0; |
| 4692 if (m_pHintTables && index != pageNum) { |
| 4693 FX_FILESIZE szPageStartPos = 0; |
| 4694 FX_FILESIZE szPageLength = 0; |
| 4695 FX_DWORD dwObjNum = 0; |
| 4696 FX_BOOL bPagePosGot = m_pHintTables->GetPagePos(index, szPageStartPos, |
| 4697 szPageLength, dwObjNum); |
| 4698 if (!bPagePosGot) { |
| 4699 return nullptr; |
| 4700 } |
| 4701 m_syntaxParser.InitParser(m_pFileRead, (FX_DWORD)szPageStartPos); |
| 4702 CPDF_Object* pPageDict = ParseIndirectObjectAt(0, dwObjNum, m_pDocument); |
| 4703 if (!pPageDict) { |
| 4704 return nullptr; |
| 4705 } |
| 4706 m_pDocument->InsertIndirectObject(dwObjNum, pPageDict); |
| 4707 return pPageDict->GetDict(); |
| 4708 } |
| 4709 } |
| 4710 return m_pDocument->GetPage(index); |
| 4711 } |
4626 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) { | 4712 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) { |
4627 if (!m_pDocument) { | 4713 if (!m_pDocument) { |
4628 return PDFFORM_AVAIL; | 4714 return PDFFORM_AVAIL; |
4629 } | 4715 } |
4630 if (!m_bLinearizedFormParamLoad) { | 4716 if (!m_bLinearizedFormParamLoad) { |
4631 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); | 4717 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); |
4632 if (!pRoot) { | 4718 if (!pRoot) { |
4633 return PDFFORM_AVAIL; | 4719 return PDFFORM_AVAIL; |
4634 } | 4720 } |
4635 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); | 4721 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4683 return FALSE; | 4769 return FALSE; |
4684 } | 4770 } |
4685 CPDF_PageNode::~CPDF_PageNode() { | 4771 CPDF_PageNode::~CPDF_PageNode() { |
4686 int32_t iSize = m_childNode.GetSize(); | 4772 int32_t iSize = m_childNode.GetSize(); |
4687 for (int32_t i = 0; i < iSize; ++i) { | 4773 for (int32_t i = 0; i < iSize; ++i) { |
4688 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; | 4774 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; |
4689 delete pNode; | 4775 delete pNode; |
4690 } | 4776 } |
4691 m_childNode.RemoveAll(); | 4777 m_childNode.RemoveAll(); |
4692 } | 4778 } |
| 4779 CPDF_HintTables::~CPDF_HintTables() { |
| 4780 m_nFirstPageSharedObjs = 0; |
| 4781 m_szFirstPageObjOffset = 0; |
| 4782 m_dwDeltaNObjsArray.RemoveAll(); |
| 4783 m_dwNSharedObjsArray.RemoveAll(); |
| 4784 m_dwSharedObjNumArray.RemoveAll(); |
| 4785 m_dwIdentifierArray.RemoveAll(); |
| 4786 m_szPageOffsetArray.RemoveAll(); |
| 4787 m_szSharedObjOffsetArray.RemoveAll(); |
| 4788 } |
| 4789 FX_DWORD CPDF_HintTables::GetItemLength(int index, |
| 4790 const CFX_FileSizeArray& szArray) { |
| 4791 if (index < 0 || index > szArray.GetSize() - 2) |
| 4792 return 0; |
| 4793 return szArray[index + 1] - szArray[index]; |
| 4794 } |
| 4795 FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { |
| 4796 if (!hStream) |
| 4797 return FALSE; |
| 4798 int nStreamOffset = ReadPrimaryHintStreamOffset(); |
| 4799 int nStreamLen = ReadPrimaryHintStreamLength(); |
| 4800 if (nStreamOffset < 0 || nStreamLen < 1) |
| 4801 return FALSE; |
| 4802 // Item 1: The least number of objects in a page. |
| 4803 FX_DWORD dwObjLeastNum = hStream->GetBits(32); |
| 4804 // Item 2: The location of the first page's page object. |
| 4805 FX_DWORD dwFirstObjLoc = hStream->GetBits(32); |
| 4806 if (dwFirstObjLoc > nStreamOffset) { |
| 4807 FX_SAFE_DWORD safeLoc = pdfium::base::checked_cast<FX_DWORD>(nStreamLen); |
| 4808 safeLoc += dwFirstObjLoc; |
| 4809 if (!safeLoc.IsValid()) |
| 4810 return FALSE; |
| 4811 m_szFirstPageObjOffset = |
| 4812 pdfium::base::checked_cast<FX_FILESIZE>(safeLoc.ValueOrDie()); |
| 4813 } else { |
| 4814 m_szFirstPageObjOffset = |
| 4815 pdfium::base::checked_cast<FX_FILESIZE>(dwFirstObjLoc); |
| 4816 } |
| 4817 // Item 3: The number of bits needed to represent the difference |
| 4818 // between the greatest and least number of objects in a page. |
| 4819 FX_DWORD dwDeltaObjectsBits = hStream->GetBits(16); |
| 4820 // Item 4: The least length of a page in bytes. |
| 4821 FX_DWORD dwPageLeastLen = hStream->GetBits(32); |
| 4822 // Item 5: The number of bits needed to represent the difference |
| 4823 // between the greatest and least length of a page, in bytes. |
| 4824 FX_DWORD dwDeltaPageLenBits = hStream->GetBits(16); |
| 4825 // Skip Item 6, 7, 8, 9 total 96 bits. |
| 4826 hStream->SkipBits(96); |
| 4827 // Item 10: The number of bits needed to represent the greatest |
| 4828 // number of shared object references. |
| 4829 FX_DWORD dwSharedObjBits = hStream->GetBits(16); |
| 4830 // Item 11: The number of bits needed to represent the numerically |
| 4831 // greatest shared object identifier used by the pages. |
| 4832 FX_DWORD dwSharedIdBits = hStream->GetBits(16); |
| 4833 // Item 12: The number of bits needed to represent the numerator of |
| 4834 // the fractional position for each shared object reference. For each |
| 4835 // shared object referenced from a page, there is an indication of |
| 4836 // where in the page's content stream the object is first referenced. |
| 4837 FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16); |
| 4838 // Item 13: Skip Item 13 which has 16 bits. |
| 4839 FX_DWORD dwSharedDenominator = hStream->GetBits(16); |
| 4840 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N")); |
| 4841 int nPages = pPageNum ? pPageNum->GetInteger() : 0; |
| 4842 if (nPages < 1) |
| 4843 return FALSE; |
| 4844 for (int i = 0; i < nPages; ++i) { |
| 4845 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); |
| 4846 safeDeltaObj += dwObjLeastNum; |
| 4847 if (!safeDeltaObj.IsValid()) |
| 4848 return FALSE; |
| 4849 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); |
| 4850 } |
| 4851 hStream->ByteAlign(); |
| 4852 CFX_DWordArray dwPageLenArray; |
| 4853 for (int i = 0; i < nPages; ++i) { |
| 4854 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); |
| 4855 safePageLen += dwPageLeastLen; |
| 4856 if (!safePageLen.IsValid()) |
| 4857 return FALSE; |
| 4858 dwPageLenArray.Add(safePageLen.ValueOrDie()); |
| 4859 } |
| 4860 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E")); |
| 4861 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1; |
| 4862 if (nOffsetE < 0) |
| 4863 return FALSE; |
| 4864 CPDF_Object* pFirstPageNum = |
| 4865 m_pLinearizedDict->GetElementValue(FX_BSTRC("P")); |
| 4866 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; |
| 4867 for (int i = 0; i < nPages; ++i) { |
| 4868 if (i == nFirstPageNum) { |
| 4869 m_szPageOffsetArray.Add(m_szFirstPageObjOffset); |
| 4870 } else if (i == nFirstPageNum + 1) { |
| 4871 if (i == 1) { |
| 4872 m_szPageOffsetArray.Add(nOffsetE); |
| 4873 } else { |
| 4874 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 2] + |
| 4875 dwPageLenArray[i - 2]); |
| 4876 } |
| 4877 } else { |
| 4878 if (i == 0) { |
| 4879 m_szPageOffsetArray.Add(nOffsetE); |
| 4880 } else { |
| 4881 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 1] + |
| 4882 dwPageLenArray[i - 1]); |
| 4883 } |
| 4884 } |
| 4885 } |
| 4886 if (nPages > 0) { |
| 4887 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] + |
| 4888 dwPageLenArray[nPages - 1]); |
| 4889 } |
| 4890 hStream->ByteAlign(); |
| 4891 // number of shared objects |
| 4892 for (int i = 0; i < nPages; i++) { |
| 4893 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); |
| 4894 } |
| 4895 hStream->ByteAlign(); |
| 4896 // array of identifier, sizes = nshared_objects |
| 4897 for (int i = 0; i < nPages; i++) { |
| 4898 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) { |
| 4899 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); |
| 4900 } |
| 4901 } |
| 4902 hStream->ByteAlign(); |
| 4903 for (int i = 0; i < nPages; i++) { |
| 4904 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; |
| 4905 safeSize *= dwSharedNumeratorBits; |
| 4906 if (!safeSize.IsValid()) |
| 4907 return FALSE; |
| 4908 hStream->SkipBits(safeSize.ValueOrDie()); |
| 4909 } |
| 4910 hStream->ByteAlign(); |
| 4911 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); |
| 4912 safeTotalPageLen *= dwDeltaPageLenBits; |
| 4913 if (!safeTotalPageLen.IsValid()) |
| 4914 return FALSE; |
| 4915 hStream->SkipBits(safeTotalPageLen.ValueOrDie()); |
| 4916 hStream->ByteAlign(); |
| 4917 return TRUE; |
| 4918 } |
| 4919 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream) { |
| 4920 if (!hStream) |
| 4921 return FALSE; |
| 4922 int nStreamOffset = ReadPrimaryHintStreamOffset(); |
| 4923 int nStreamLen = ReadPrimaryHintStreamLength(); |
| 4924 if (nStreamOffset < 0 || nStreamLen < 1) |
| 4925 return FALSE; |
| 4926 // Item 1: The object number of the first object in the shared objects |
| 4927 // section. |
| 4928 FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32); |
| 4929 // Item 2: The location of the first object in the shared objects section. |
| 4930 FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32); |
| 4931 if (dwFirstSharedObjLoc > nStreamOffset) |
| 4932 dwFirstSharedObjLoc += nStreamLen; |
| 4933 // Item 3: The number of shared object entries for the first page. |
| 4934 m_nFirstPageSharedObjs = hStream->GetBits(32); |
| 4935 // Item 4: The number of shared object entries for the shared objects |
| 4936 // section, including the number of shared object entries for the first page. |
| 4937 FX_DWORD dwSharedObjTotal = hStream->GetBits(32); |
| 4938 // Item 5: The number of bits needed to represent the greatest number of |
| 4939 // objects in a shared object group. Skipped. |
| 4940 hStream->SkipBits(16); |
| 4941 // Item 6: The least length of a shared object group in bytes. |
| 4942 FX_DWORD dwGroupLeastLen = hStream->GetBits(32); |
| 4943 // Item 7: The number of bits needed to represent the difference between the |
| 4944 // greatest and least length of a shared object group, in bytes. |
| 4945 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); |
| 4946 CPDF_Object* pFirstPageObj = |
| 4947 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); |
| 4948 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; |
| 4949 if (nFirstPageObjNum < 0) |
| 4950 return FALSE; |
| 4951 FX_DWORD dwPrevObjLen = 0; |
| 4952 FX_DWORD dwCurObjLen = 0; |
| 4953 for (int i = 0; i < dwSharedObjTotal; ++i) { |
| 4954 dwPrevObjLen = dwCurObjLen; |
| 4955 FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen); |
| 4956 safeObjLen += dwGroupLeastLen; |
| 4957 if (!safeObjLen.IsValid()) |
| 4958 return FALSE; |
| 4959 dwCurObjLen = safeObjLen.ValueOrDie(); |
| 4960 if (i < m_nFirstPageSharedObjs) { |
| 4961 m_dwSharedObjNumArray.Add(nFirstPageObjNum + i); |
| 4962 if (i == 0) |
| 4963 m_szSharedObjOffsetArray.Add(m_szFirstPageObjOffset); |
| 4964 } else { |
| 4965 FX_SAFE_DWORD safeObjNum = dwFirstSharedObjNum; |
| 4966 safeObjNum += i - m_nFirstPageSharedObjs; |
| 4967 if (safeObjNum.IsValid()) |
| 4968 return FALSE; |
| 4969 m_dwSharedObjNumArray.Add(safeObjNum.ValueOrDie()); |
| 4970 if (i == m_nFirstPageSharedObjs) |
| 4971 m_szSharedObjOffsetArray.Add( |
| 4972 pdfium::base::checked_cast<int32_t>(dwFirstSharedObjLoc)); |
| 4973 } |
| 4974 if (i != 0 && i != m_nFirstPageSharedObjs) { |
| 4975 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwPrevObjLen); |
| 4976 safeLoc += m_szSharedObjOffsetArray[i - 1]; |
| 4977 if (!safeLoc.IsValid()) |
| 4978 return FALSE; |
| 4979 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie()); |
| 4980 } |
| 4981 } |
| 4982 if (dwSharedObjTotal > 0) { |
| 4983 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwCurObjLen); |
| 4984 safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1]; |
| 4985 if (!safeLoc.IsValid()) |
| 4986 return FALSE; |
| 4987 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie()); |
| 4988 } |
| 4989 hStream->ByteAlign(); |
| 4990 hStream->SkipBits(dwSharedObjTotal); |
| 4991 hStream->ByteAlign(); |
| 4992 return TRUE; |
| 4993 } |
| 4994 FX_BOOL CPDF_HintTables::GetPagePos(int index, |
| 4995 FX_FILESIZE& szPageStartPos, |
| 4996 FX_FILESIZE& szPageLength, |
| 4997 FX_DWORD& dwObjNum) { |
| 4998 if (!m_pLinearizedDict) |
| 4999 return FALSE; |
| 5000 szPageStartPos = m_szPageOffsetArray[index]; |
| 5001 szPageLength = GetItemLength(index, m_szPageOffsetArray); |
| 5002 CPDF_Object* pFirstPageNum = |
| 5003 m_pLinearizedDict->GetElementValue(FX_BSTRC("P")); |
| 5004 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; |
| 5005 CPDF_Object* pFirstPageObjNum = |
| 5006 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); |
| 5007 if (!pFirstPageObjNum) |
| 5008 return FALSE; |
| 5009 int nFirstPageObjNum = pFirstPageObjNum->GetInteger(); |
| 5010 if (index == nFirstPageNum) { |
| 5011 dwObjNum = nFirstPageObjNum; |
| 5012 return TRUE; |
| 5013 } |
| 5014 // The object number of remaining pages starts from 1. |
| 5015 dwObjNum = 1; |
| 5016 for (int i = 0; i < index; ++i) { |
| 5017 if (i == nFirstPageNum) |
| 5018 continue; |
| 5019 dwObjNum += m_dwDeltaNObjsArray[i]; |
| 5020 } |
| 5021 return TRUE; |
| 5022 } |
| 5023 FX_BOOL CPDF_HintTables::CheckPage(int index, IFX_DownloadHints* pHints) { |
| 5024 if (!m_pLinearizedDict) |
| 5025 return FALSE; |
| 5026 CPDF_Object* pFirstAvailPage = |
| 5027 m_pLinearizedDict->GetElementValue(FX_BSTRC("P")); |
| 5028 int nFirstAvailPage = pFirstAvailPage ? pFirstAvailPage->GetInteger() : 0; |
| 5029 if (index == nFirstAvailPage) |
| 5030 return TRUE; |
| 5031 FX_DWORD dwLength = GetItemLength(index, m_szPageOffsetArray); |
| 5032 if (!dwLength || |
| 5033 !m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength, |
| 5034 pHints)) { |
| 5035 return FALSE; |
| 5036 } |
| 5037 // Download data of shared objects in the page. |
| 5038 FX_DWORD offset = 0; |
| 5039 for (int i = 0; i < index; ++i) { |
| 5040 offset += m_dwNSharedObjsArray[i]; |
| 5041 } |
| 5042 CPDF_Object* pFirstPageObj = |
| 5043 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); |
| 5044 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; |
| 5045 if (nFirstPageObjNum < 0) |
| 5046 return FALSE; |
| 5047 FX_DWORD dwIndex = 0; |
| 5048 FX_DWORD dwObjNum = 0; |
| 5049 for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) { |
| 5050 dwIndex = m_dwIdentifierArray[offset + j]; |
| 5051 dwObjNum = m_dwSharedObjNumArray[dwIndex]; |
| 5052 if (dwObjNum >= nFirstPageObjNum && |
| 5053 dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) { |
| 5054 continue; |
| 5055 } |
| 5056 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray); |
| 5057 if (!dwLength || |
| 5058 !m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, |
| 5059 pHints)) { |
| 5060 return FALSE; |
| 5061 } |
| 5062 } |
| 5063 return TRUE; |
| 5064 } |
| 5065 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { |
| 5066 if (!pHintStream || !m_pLinearizedDict) |
| 5067 return FALSE; |
| 5068 CPDF_Dictionary* pDict = pHintStream->GetDict(); |
| 5069 CPDF_Object* pOffset = pDict ? pDict->GetElement(FX_BSTRC("S")) : nullptr; |
| 5070 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER) |
| 5071 return FALSE; |
| 5072 CPDF_StreamAcc acc; |
| 5073 acc.LoadAllData(pHintStream); |
| 5074 FX_DWORD size = acc.GetSize(); |
| 5075 // The header section of page offset hint table is 36 bytes. |
| 5076 // The header section of shared object hint table is 24 bytes. |
| 5077 // Hint table has at least 60 bytes. |
| 5078 const FX_DWORD MIN_STREAM_LEN = 60; |
| 5079 if (size < MIN_STREAM_LEN || size < pOffset->GetInteger() || |
| 5080 !pOffset->GetInteger()) { |
| 5081 return FALSE; |
| 5082 } |
| 5083 CFX_BitStream bs; |
| 5084 bs.Init(acc.GetData(), size); |
| 5085 return ReadPageHintTable(&bs) && ReadSharedObjHintTable(&bs); |
| 5086 } |
| 5087 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { |
| 5088 if (!m_pLinearizedDict) |
| 5089 return -1; |
| 5090 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); |
| 5091 if (!pRange) |
| 5092 return -1; |
| 5093 CPDF_Object* pStreamOffset = pRange->GetElementValue(0); |
| 5094 if (!pStreamOffset) |
| 5095 return -1; |
| 5096 return pStreamOffset->GetInteger(); |
| 5097 } |
| 5098 int CPDF_HintTables::ReadPrimaryHintStreamLength() const { |
| 5099 if (!m_pLinearizedDict) |
| 5100 return -1; |
| 5101 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); |
| 5102 if (!pRange) |
| 5103 return -1; |
| 5104 CPDF_Object* pStreamLen = pRange->GetElementValue(1); |
| 5105 if (!pStreamLen) |
| 5106 return -1; |
| 5107 return pStreamLen->GetInteger(); |
| 5108 } |
OLD | NEW |