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 "../../../../third_party/base/nonstd_unique_ptr.h" | 11 #include "../../../../third_party/base/nonstd_unique_ptr.h" |
12 #include "../../../include/fpdfapi/fpdf_module.h" | 12 #include "../../../include/fpdfapi/fpdf_module.h" |
13 #include "../../../include/fpdfapi/fpdf_page.h" | 13 #include "../../../include/fpdfapi/fpdf_page.h" |
14 #include "../../../include/fpdfapi/fpdf_parser.h" | 14 #include "../../../include/fpdfapi/fpdf_parser.h" |
15 #include "../../../include/fxcrt/fx_safe_types.h" | 15 #include "../../../include/fxcrt/fx_safe_types.h" |
16 #include "../fpdf_page/pageint.h" | 16 #include "../fpdf_page/pageint.h" |
17 #include "parser_int.h" | |
17 | 18 |
18 namespace { | 19 namespace { |
19 | 20 |
20 int CompareFileSize(const void* p1, const void* p2) { | 21 int CompareFileSize(const void* p1, const void* p2) { |
21 return *(FX_FILESIZE*)p1 - *(FX_FILESIZE*)p2; | 22 return *(FX_FILESIZE*)p1 - *(FX_FILESIZE*)p2; |
22 } | 23 } |
23 | 24 |
24 int32_t GetHeaderOffset(IFX_FileRead* pFile) { | 25 int32_t GetHeaderOffset(IFX_FileRead* pFile) { |
25 const FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025); | 26 const FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025); |
26 const size_t kBufSize = 4; | 27 const size_t kBufSize = 4; |
(...skipping 2744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2771 } | 2772 } |
2772 buffer[offset++] = ch; | 2773 buffer[offset++] = ch; |
2773 if (offset == size) { | 2774 if (offset == size) { |
2774 break; | 2775 break; |
2775 } | 2776 } |
2776 } | 2777 } |
2777 } | 2778 } |
2778 | 2779 |
2779 class CPDF_DataAvail final : public IPDF_DataAvail { | 2780 class CPDF_DataAvail final : public IPDF_DataAvail { |
2780 public: | 2781 public: |
2781 CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); | 2782 CPDF_DataAvail(IFX_FileAvail* pFileAvail, |
2783 IFX_FileRead* pFileRead, | |
2784 FX_BOOL bSupportHintTable); | |
2782 ~CPDF_DataAvail() override; | 2785 ~CPDF_DataAvail() override; |
2783 | 2786 |
2784 FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; | 2787 FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; |
2785 | 2788 |
2786 void SetDocument(CPDF_Document* pDoc) override; | 2789 void SetDocument(CPDF_Document* pDoc) override; |
2787 | 2790 |
2788 FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; | 2791 FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; |
2789 | 2792 |
2790 int32_t IsFormAvail(IFX_DownloadHints* pHints) override; | 2793 int32_t IsFormAvail(IFX_DownloadHints* pHints) override; |
2791 | 2794 |
2792 int32_t IsLinearizedPDF() override; | 2795 int32_t IsLinearizedPDF() override; |
2793 | 2796 |
2794 FX_BOOL IsLinearized() override { return m_bLinearized; } | 2797 FX_BOOL IsLinearized() override { return m_bLinearized; } |
2795 | 2798 |
2796 void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, FX_DWORD* pSize) override; | 2799 void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, FX_DWORD* pSize) override; |
2800 int GetPageCount() const; | |
2801 CPDF_Dictionary* GetPage(int index); | |
2802 | |
2803 friend class CPDF_HintTables; | |
2797 | 2804 |
2798 protected: | 2805 protected: |
2799 static const int kMaxDataAvailRecursionDepth = 64; | 2806 static const int kMaxDataAvailRecursionDepth = 64; |
2800 static int s_CurrentDataAvailRecursionDepth; | 2807 static int s_CurrentDataAvailRecursionDepth; |
2801 | 2808 |
2802 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); | 2809 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); |
2803 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, | 2810 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, |
2804 FX_BOOL bParsePage, | 2811 FX_BOOL bParsePage, |
2805 IFX_DownloadHints* pHints, | 2812 IFX_DownloadHints* pHints, |
2806 CFX_PtrArray& ret_array); | 2813 CFX_PtrArray& ret_array); |
2807 FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints); | 2814 FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints); |
2808 FX_BOOL CheckHeader(IFX_DownloadHints* pHints); | 2815 FX_BOOL CheckHeader(IFX_DownloadHints* pHints); |
2809 FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints); | 2816 FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints); |
2817 FX_BOOL CheckHintTables(IFX_DownloadHints* pHints); | |
2810 FX_BOOL CheckEnd(IFX_DownloadHints* pHints); | 2818 FX_BOOL CheckEnd(IFX_DownloadHints* pHints); |
2811 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); | 2819 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); |
2812 FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints); | 2820 FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints); |
2813 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); | 2821 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); |
2814 FX_BOOL CheckRoot(IFX_DownloadHints* pHints); | 2822 FX_BOOL CheckRoot(IFX_DownloadHints* pHints); |
2815 FX_BOOL CheckInfo(IFX_DownloadHints* pHints); | 2823 FX_BOOL CheckInfo(IFX_DownloadHints* pHints); |
2816 FX_BOOL CheckPages(IFX_DownloadHints* pHints); | 2824 FX_BOOL CheckPages(IFX_DownloadHints* pHints); |
2817 FX_BOOL CheckPage(IFX_DownloadHints* pHints); | 2825 FX_BOOL CheckPage(IFX_DownloadHints* pHints); |
2818 FX_BOOL CheckResources(IFX_DownloadHints* pHints); | 2826 FX_BOOL CheckResources(IFX_DownloadHints* pHints); |
2819 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); | 2827 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); |
2820 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); | 2828 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); |
2821 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); | 2829 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); |
2822 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); | 2830 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); |
2823 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); | 2831 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); |
2824 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints); | 2832 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints); |
2825 | 2833 |
2826 int32_t CheckCrossRefStream(IFX_DownloadHints* pHints, | 2834 int32_t CheckCrossRefStream(IFX_DownloadHints* pHints, |
2827 FX_FILESIZE& xref_offset); | 2835 FX_FILESIZE& xref_offset); |
2828 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); | 2836 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); |
2829 void SetStartOffset(FX_FILESIZE dwOffset); | 2837 void SetStartOffset(FX_FILESIZE dwOffset); |
2830 FX_BOOL GetNextToken(CFX_ByteString& token); | 2838 FX_BOOL GetNextToken(CFX_ByteString& token); |
2831 FX_BOOL GetNextChar(uint8_t& ch); | 2839 FX_BOOL GetNextChar(uint8_t& ch); |
2832 CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum); | 2840 CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos, |
2841 FX_DWORD objnum, | |
2842 CPDF_IndirectObjects* pObjList = NULL); | |
2833 CPDF_Object* GetObject(FX_DWORD objnum, | 2843 CPDF_Object* GetObject(FX_DWORD objnum, |
2834 IFX_DownloadHints* pHints, | 2844 IFX_DownloadHints* pHints, |
2835 FX_BOOL* pExistInFile); | 2845 FX_BOOL* pExistInFile); |
2836 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); | 2846 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); |
2837 FX_BOOL PreparePageItem(); | 2847 FX_BOOL PreparePageItem(); |
2838 FX_BOOL LoadPages(IFX_DownloadHints* pHints); | 2848 FX_BOOL LoadPages(IFX_DownloadHints* pHints); |
2839 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); | 2849 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); |
2840 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); | 2850 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); |
2841 FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); | 2851 FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); |
2842 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); | 2852 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); |
(...skipping 10 matching lines...) Expand all Loading... | |
2853 IFX_DownloadHints* pHints); | 2863 IFX_DownloadHints* pHints); |
2854 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, | 2864 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, |
2855 CPDF_PageNode* pPageNode, | 2865 CPDF_PageNode* pPageNode, |
2856 IFX_DownloadHints* pHints); | 2866 IFX_DownloadHints* pHints); |
2857 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, | 2867 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, |
2858 CPDF_PageNode* pPageNode, | 2868 CPDF_PageNode* pPageNode, |
2859 IFX_DownloadHints* pHints); | 2869 IFX_DownloadHints* pHints); |
2860 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); | 2870 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); |
2861 FX_BOOL IsFirstCheck(int iPage); | 2871 FX_BOOL IsFirstCheck(int iPage); |
2862 void ResetFirstCheck(int iPage); | 2872 void ResetFirstCheck(int iPage); |
2873 FX_BOOL IsDataAvail(FX_FILESIZE offset, | |
2874 FX_DWORD size, | |
2875 IFX_DownloadHints* pHints); | |
2863 | 2876 |
2864 CPDF_Parser m_parser; | 2877 CPDF_Parser m_parser; |
2865 | 2878 |
2866 CPDF_SyntaxParser m_syntaxParser; | 2879 CPDF_SyntaxParser m_syntaxParser; |
2867 | 2880 |
2868 CPDF_Object* m_pRoot; | 2881 CPDF_Object* m_pRoot; |
2869 | 2882 |
2870 FX_DWORD m_dwRootObjNum; | 2883 FX_DWORD m_dwRootObjNum; |
2871 | 2884 |
2872 FX_DWORD m_dwInfoObjNum; | 2885 FX_DWORD m_dwInfoObjNum; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2966 FX_FILESIZE m_dwPrevXRefOffset; | 2979 FX_FILESIZE m_dwPrevXRefOffset; |
2967 | 2980 |
2968 FX_BOOL m_bTotalLoadPageTree; | 2981 FX_BOOL m_bTotalLoadPageTree; |
2969 | 2982 |
2970 FX_BOOL m_bCurPageDictLoadOK; | 2983 FX_BOOL m_bCurPageDictLoadOK; |
2971 | 2984 |
2972 CPDF_PageNode m_pageNodes; | 2985 CPDF_PageNode m_pageNodes; |
2973 | 2986 |
2974 std::set<FX_DWORD> m_pageMapCheckState; | 2987 std::set<FX_DWORD> m_pageMapCheckState; |
2975 std::set<FX_DWORD> m_pagesLoadState; | 2988 std::set<FX_DWORD> m_pagesLoadState; |
2989 | |
2990 nonstd::unique_ptr<CPDF_HintTables> m_pHintTables; | |
2991 FX_BOOL m_bSupportHintTable; | |
2976 }; | 2992 }; |
2977 | 2993 |
2978 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, | 2994 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, |
2979 IFX_FileRead* pFileRead) | 2995 IFX_FileRead* pFileRead) |
2980 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} | 2996 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} |
2981 | 2997 |
2982 // static | 2998 // static |
2983 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, | 2999 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, |
2984 IFX_FileRead* pFileRead) { | 3000 IFX_FileRead* pFileRead) { |
2985 return new CPDF_DataAvail(pFileAvail, pFileRead); | 3001 return new CPDF_DataAvail(pFileAvail, pFileRead, FALSE); |
2986 } | 3002 } |
2987 | 3003 |
2988 // static | 3004 // static |
2989 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; | 3005 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; |
2990 | 3006 |
2991 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, | 3007 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, |
2992 IFX_FileRead* pFileRead) | 3008 IFX_FileRead* pFileRead, |
3009 FX_BOOL bSupportHintTable) | |
2993 : IPDF_DataAvail(pFileAvail, pFileRead) { | 3010 : IPDF_DataAvail(pFileAvail, pFileRead) { |
2994 m_Pos = 0; | 3011 m_Pos = 0; |
2995 m_dwFileLen = 0; | 3012 m_dwFileLen = 0; |
2996 if (m_pFileRead) { | 3013 if (m_pFileRead) { |
2997 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); | 3014 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); |
2998 } | 3015 } |
2999 m_dwCurrentOffset = 0; | 3016 m_dwCurrentOffset = 0; |
3000 m_WordSize = 0; | 3017 m_WordSize = 0; |
3001 m_dwXRefOffset = 0; | 3018 m_dwXRefOffset = 0; |
3002 m_bufferOffset = 0; | 3019 m_bufferOffset = 0; |
(...skipping 25 matching lines...) Expand all Loading... | |
3028 m_pTrailer = NULL; | 3045 m_pTrailer = NULL; |
3029 m_pCurrentParser = NULL; | 3046 m_pCurrentParser = NULL; |
3030 m_pAcroForm = NULL; | 3047 m_pAcroForm = NULL; |
3031 m_pPageDict = NULL; | 3048 m_pPageDict = NULL; |
3032 m_pPageResource = NULL; | 3049 m_pPageResource = NULL; |
3033 m_docStatus = PDF_DATAAVAIL_HEADER; | 3050 m_docStatus = PDF_DATAAVAIL_HEADER; |
3034 m_parser.m_bOwnFileRead = FALSE; | 3051 m_parser.m_bOwnFileRead = FALSE; |
3035 m_bTotalLoadPageTree = FALSE; | 3052 m_bTotalLoadPageTree = FALSE; |
3036 m_bCurPageDictLoadOK = FALSE; | 3053 m_bCurPageDictLoadOK = FALSE; |
3037 m_bLinearedDataOK = FALSE; | 3054 m_bLinearedDataOK = FALSE; |
3055 m_bSupportHintTable = bSupportHintTable; | |
3038 } | 3056 } |
3039 CPDF_DataAvail::~CPDF_DataAvail() { | 3057 CPDF_DataAvail::~CPDF_DataAvail() { |
3040 if (m_pLinearized) { | 3058 if (m_pLinearized) { |
3041 m_pLinearized->Release(); | 3059 m_pLinearized->Release(); |
3042 } | 3060 } |
3043 if (m_pRoot) { | 3061 if (m_pRoot) { |
3044 m_pRoot->Release(); | 3062 m_pRoot->Release(); |
3045 } | 3063 } |
3046 if (m_pTrailer) { | 3064 if (m_pTrailer) { |
3047 m_pTrailer->Release(); | 3065 m_pTrailer->Release(); |
3048 } | 3066 } |
3049 int32_t i = 0; | 3067 |
3050 int32_t iSize = m_arrayAcroforms.GetSize(); | 3068 int32_t iSize = m_arrayAcroforms.GetSize(); |
3051 for (i = 0; i < iSize; ++i) { | 3069 for (int i = 0; i < iSize; ++i) { |
3052 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release(); | 3070 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release(); |
3053 } | 3071 } |
3054 } | 3072 } |
3055 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { | 3073 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { |
3056 m_pDocument = pDoc; | 3074 m_pDocument = pDoc; |
3057 } | 3075 } |
3058 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { | 3076 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { |
3059 CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser()); | 3077 CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser()); |
3060 if (pParser == NULL) { | 3078 if (pParser == NULL) { |
3061 return 0; | 3079 return 0; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3123 value = pDict->GetNextElement(pos, key); | 3141 value = pDict->GetNextElement(pos, key); |
3124 if (key != "Parent") { | 3142 if (key != "Parent") { |
3125 new_obj_array.Add(value); | 3143 new_obj_array.Add(value); |
3126 } | 3144 } |
3127 } | 3145 } |
3128 } break; | 3146 } break; |
3129 case PDFOBJ_REFERENCE: { | 3147 case PDFOBJ_REFERENCE: { |
3130 CPDF_Reference* pRef = (CPDF_Reference*)pObj; | 3148 CPDF_Reference* pRef = (CPDF_Reference*)pObj; |
3131 FX_DWORD dwNum = pRef->GetRefObjNum(); | 3149 FX_DWORD dwNum = pRef->GetRefObjNum(); |
3132 FX_FILESIZE offset; | 3150 FX_FILESIZE offset; |
3133 FX_DWORD original_size = GetObjectSize(dwNum, offset); | 3151 FX_DWORD size = GetObjectSize(dwNum, offset); |
3134 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; | 3152 if (size == 0 || offset < 0 || offset >= m_dwFileLen) { |
3135 if (size.ValueOrDefault(0) == 0 || offset < 0 || | |
3136 offset >= m_dwFileLen) { | |
3137 break; | 3153 break; |
3138 } | 3154 } |
3139 | 3155 if (!IsDataAvail(offset, size, pHints)) { |
3140 size += offset; | |
3141 size += 512; | |
3142 if (!size.IsValid()) { | |
3143 break; | |
3144 } | |
3145 if (size.ValueOrDie() > m_dwFileLen) { | |
3146 size = m_dwFileLen - offset; | |
3147 } else { | |
3148 size = original_size + 512; | |
3149 } | |
3150 if (!size.IsValid()) { | |
3151 break; | |
3152 } | |
3153 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { | |
3154 pHints->AddSegment(offset, size.ValueOrDie()); | |
3155 ret_array.Add(pObj); | 3156 ret_array.Add(pObj); |
3156 count++; | 3157 count++; |
3157 } else if (!m_objnum_array.Find(dwNum)) { | 3158 } else if (!m_objnum_array.Find(dwNum)) { |
3158 m_objnum_array.AddObjNum(dwNum); | 3159 m_objnum_array.AddObjNum(dwNum); |
3159 CPDF_Object* pReferred = | 3160 CPDF_Object* pReferred = |
3160 m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL); | 3161 m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL); |
3161 if (pReferred) { | 3162 if (pReferred) { |
3162 new_obj_array.Add(pReferred); | 3163 new_obj_array.Add(pReferred); |
3163 } | 3164 } |
3164 } | 3165 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3244 m_docStatus = PDF_DATAAVAIL_PAGETREE; | 3245 m_docStatus = PDF_DATAAVAIL_PAGETREE; |
3245 return TRUE; | 3246 return TRUE; |
3246 } | 3247 } |
3247 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { | 3248 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { |
3248 switch (m_docStatus) { | 3249 switch (m_docStatus) { |
3249 case PDF_DATAAVAIL_HEADER: | 3250 case PDF_DATAAVAIL_HEADER: |
3250 return CheckHeader(pHints); | 3251 return CheckHeader(pHints); |
3251 case PDF_DATAAVAIL_FIRSTPAGE: | 3252 case PDF_DATAAVAIL_FIRSTPAGE: |
3252 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: | 3253 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: |
3253 return CheckFirstPage(pHints); | 3254 return CheckFirstPage(pHints); |
3255 case PDF_DATAAVAIL_HINTTABLE: | |
3256 return CheckHintTables(pHints); | |
3254 case PDF_DATAAVAIL_END: | 3257 case PDF_DATAAVAIL_END: |
3255 return CheckEnd(pHints); | 3258 return CheckEnd(pHints); |
3256 case PDF_DATAAVAIL_CROSSREF: | 3259 case PDF_DATAAVAIL_CROSSREF: |
3257 return CheckCrossRef(pHints); | 3260 return CheckCrossRef(pHints); |
3258 case PDF_DATAAVAIL_CROSSREF_ITEM: | 3261 case PDF_DATAAVAIL_CROSSREF_ITEM: |
3259 return CheckCrossRefItem(pHints); | 3262 return CheckCrossRefItem(pHints); |
3260 case PDF_DATAAVAIL_CROSSREF_STREAM: | 3263 case PDF_DATAAVAIL_CROSSREF_STREAM: |
3261 return CheckAllCrossRefStream(pHints); | 3264 return CheckAllCrossRefStream(pHints); |
3262 case PDF_DATAAVAIL_TRAILER: | 3265 case PDF_DATAAVAIL_TRAILER: |
3263 return CheckTrailer(pHints); | 3266 return CheckTrailer(pHints); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3328 CompareFileSize); | 3331 CompareFileSize); |
3329 m_dwRootObjNum = m_parser.GetRootObjNum(); | 3332 m_dwRootObjNum = m_parser.GetRootObjNum(); |
3330 m_dwInfoObjNum = m_parser.GetInfoObjNum(); | 3333 m_dwInfoObjNum = m_parser.GetInfoObjNum(); |
3331 m_pCurrentParser = &m_parser; | 3334 m_pCurrentParser = &m_parser; |
3332 m_docStatus = PDF_DATAAVAIL_ROOT; | 3335 m_docStatus = PDF_DATAAVAIL_ROOT; |
3333 return TRUE; | 3336 return TRUE; |
3334 } | 3337 } |
3335 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, | 3338 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, |
3336 IFX_DownloadHints* pHints, | 3339 IFX_DownloadHints* pHints, |
3337 FX_BOOL* pExistInFile) { | 3340 FX_BOOL* pExistInFile) { |
3338 CPDF_Object* pRet = NULL; | 3341 CPDF_Object* pRet = nullptr; |
3339 FX_DWORD original_size = 0; | 3342 FX_DWORD size = 0; |
3340 FX_FILESIZE offset = 0; | 3343 FX_FILESIZE offset = 0; |
3341 CPDF_Parser* pParser = NULL; | 3344 CPDF_Parser* pParser = nullptr; |
3342 | 3345 if (pExistInFile) |
3343 if (pExistInFile) { | |
3344 *pExistInFile = TRUE; | 3346 *pExistInFile = TRUE; |
3345 } | |
3346 | 3347 |
3347 if (m_pDocument == NULL) { | 3348 if (m_pDocument == NULL) { |
3348 original_size = (FX_DWORD)m_parser.GetObjectSize(objnum); | 3349 size = (FX_DWORD)m_parser.GetObjectSize(objnum); |
3349 offset = m_parser.GetObjectOffset(objnum); | 3350 offset = m_parser.GetObjectOffset(objnum); |
3350 pParser = &m_parser; | 3351 pParser = &m_parser; |
3351 } else { | 3352 } else { |
3352 original_size = GetObjectSize(objnum, offset); | 3353 size = GetObjectSize(objnum, offset); |
3353 pParser = (CPDF_Parser*)(m_pDocument->GetParser()); | 3354 pParser = (CPDF_Parser*)(m_pDocument->GetParser()); |
3354 } | 3355 } |
3355 | 3356 if (!IsDataAvail(offset, size, pHints)) { |
3356 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; | 3357 return nullptr; |
3357 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) { | |
3358 if (pExistInFile) | |
3359 *pExistInFile = FALSE; | |
3360 | |
3361 return NULL; | |
3362 } | 3358 } |
3363 | |
3364 size += offset; | |
3365 size += 512; | |
3366 if (!size.IsValid()) { | |
3367 return NULL; | |
3368 } | |
3369 | |
3370 if (size.ValueOrDie() > m_dwFileLen) { | |
3371 size = m_dwFileLen - offset; | |
3372 } else { | |
3373 size = original_size + 512; | |
3374 } | |
3375 | |
3376 if (!size.IsValid()) { | |
3377 return NULL; | |
3378 } | |
3379 | |
3380 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { | |
3381 pHints->AddSegment(offset, size.ValueOrDie()); | |
3382 return NULL; | |
3383 } | |
3384 | |
3385 if (pParser) { | 3359 if (pParser) { |
3386 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); | 3360 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); |
3387 } | 3361 } |
3388 | 3362 |
3389 if (!pRet && pExistInFile) { | 3363 if (!pRet && pExistInFile) { |
3390 *pExistInFile = FALSE; | 3364 *pExistInFile = FALSE; |
3391 } | 3365 } |
3392 | 3366 |
3393 return pRet; | 3367 return pRet; |
3394 } | 3368 } |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3675 FX_FILESIZE offset = m_dwLastXRefOffset; | 3649 FX_FILESIZE offset = m_dwLastXRefOffset; |
3676 if (dwSize < 512 && dwFileLen > 512) { | 3650 if (dwSize < 512 && dwFileLen > 512) { |
3677 dwSize = 512; | 3651 dwSize = 512; |
3678 offset = dwFileLen - 512; | 3652 offset = dwFileLen - 512; |
3679 } | 3653 } |
3680 pHints->AddSegment(offset, dwSize); | 3654 pHints->AddSegment(offset, dwSize); |
3681 } | 3655 } |
3682 } else { | 3656 } else { |
3683 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; | 3657 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; |
3684 } | 3658 } |
3685 if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { | 3659 if (bNeedDownLoad || m_docStatus != PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { |
3660 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; | |
3661 return FALSE; | |
3662 } | |
3663 m_docStatus = | |
3664 m_bSupportHintTable ? PDF_DATAAVAIL_HINTTABLE : PDF_DATAAVAIL_DONE; | |
3665 return TRUE; | |
3666 } | |
3667 FX_BOOL CPDF_DataAvail::IsDataAvail(FX_FILESIZE offset, | |
3668 FX_DWORD size, | |
3669 IFX_DownloadHints* pHints) { | |
3670 if (!pHints || offset > m_dwFileLen) | |
3671 return TRUE; | |
3672 FX_SAFE_DWORD safeSize = pdfium::base::checked_cast<FX_DWORD>(offset); | |
3673 safeSize += size; | |
3674 safeSize += 512; | |
3675 if (!safeSize.IsValid() || safeSize.ValueOrDie() > m_dwFileLen) | |
3676 size = m_dwFileLen - offset; | |
3677 else | |
3678 size += 512; | |
3679 if (!m_pFileAvail->IsDataAvail(offset, size)) { | |
3680 pHints->AddSegment(offset, size); | |
3681 return FALSE; | |
3682 } | |
3683 return TRUE; | |
3684 } | |
3685 FX_BOOL CPDF_DataAvail::CheckHintTables(IFX_DownloadHints* pHints) { | |
3686 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); | |
3687 if (!pDict || !pHints) { | |
3688 return TRUE; | |
yali_he
2015/10/21 07:07:44
m_docStatus should be set as PDF_DATAAVAIL_DONE be
| |
3689 } | |
3690 if (!pDict->KeyExist(FX_BSTRC("H")) || !pDict->KeyExist(FX_BSTRC("O")) || | |
3691 !pDict->KeyExist(FX_BSTRC("N"))) { | |
3686 m_docStatus = PDF_DATAAVAIL_DONE; | 3692 m_docStatus = PDF_DATAAVAIL_DONE; |
3687 return TRUE; | 3693 return TRUE; |
3688 } | 3694 } |
3689 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; | 3695 int nPageCount = pDict->GetElementValue(FX_BSTRC("N"))->GetInteger(); |
3690 return FALSE; | 3696 if (nPageCount <= 1) { |
3697 m_docStatus = PDF_DATAAVAIL_DONE; | |
3698 return TRUE; | |
3699 } | |
3700 CPDF_Array* pHintStreamRange = pDict->GetArray(FX_BSTRC("H")); | |
3701 FX_FILESIZE szHSStart = | |
3702 pHintStreamRange->GetElementValue(0) | |
3703 ? pHintStreamRange->GetElementValue(0)->GetInteger() | |
3704 : 0; | |
3705 FX_FILESIZE szHSLength = | |
3706 pHintStreamRange->GetElementValue(1) | |
3707 ? pHintStreamRange->GetElementValue(1)->GetInteger() | |
3708 : 0; | |
3709 if (szHSStart < 0 || szHSLength <= 0) { | |
3710 m_docStatus = PDF_DATAAVAIL_DONE; | |
3711 return TRUE; | |
3712 } | |
3713 if (!IsDataAvail(szHSStart, szHSLength, pHints)) { | |
3714 return FALSE; | |
3715 } | |
3716 m_syntaxParser.InitParser(m_pFileRead, m_dwHeaderOffset); | |
3717 nonstd::unique_ptr<CPDF_HintTables> pHintTables( | |
3718 new CPDF_HintTables(this, pDict)); | |
3719 CPDF_Stream* pHintStream = (CPDF_Stream*)ParseIndirectObjectAt(szHSStart, 0); | |
3720 if (!pHintStream || pHintStream->GetType() != PDFOBJ_STREAM) { | |
3721 return FALSE; | |
yali_he
2015/10/19 13:24:35
m_docStatus should be set as PDF_DATAAVAIL_DONE be
| |
3722 } | |
3723 if (pHintTables && !pHintTables->LoadHintStream(pHintStream)) { | |
3724 return FALSE; | |
yali_he
2015/10/19 13:24:35
The same as above.
| |
3725 } | |
3726 m_pHintTables.reset(pHintTables.release()); | |
3727 m_docStatus = PDF_DATAAVAIL_DONE; | |
3728 return TRUE; | |
3691 } | 3729 } |
3692 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, | 3730 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt( |
3693 FX_DWORD objnum) { | 3731 FX_FILESIZE pos, |
3732 FX_DWORD objnum, | |
3733 CPDF_IndirectObjects* pObjList) { | |
3694 FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); | 3734 FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); |
3695 m_syntaxParser.RestorePos(pos); | 3735 m_syntaxParser.RestorePos(pos); |
3696 FX_BOOL bIsNumber; | 3736 FX_BOOL bIsNumber; |
3697 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); | 3737 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); |
3698 if (!bIsNumber) { | 3738 if (!bIsNumber) { |
3699 return NULL; | 3739 return NULL; |
3700 } | 3740 } |
3701 FX_DWORD parser_objnum = FXSYS_atoi(word); | 3741 FX_DWORD parser_objnum = FXSYS_atoi(word); |
3702 if (objnum && parser_objnum != objnum) { | 3742 if (objnum && parser_objnum != objnum) { |
3703 return NULL; | 3743 return NULL; |
3704 } | 3744 } |
3705 word = m_syntaxParser.GetNextWord(bIsNumber); | 3745 word = m_syntaxParser.GetNextWord(bIsNumber); |
3706 if (!bIsNumber) { | 3746 if (!bIsNumber) { |
3707 return NULL; | 3747 return NULL; |
3708 } | 3748 } |
3709 FX_DWORD gennum = FXSYS_atoi(word); | 3749 FX_DWORD gennum = FXSYS_atoi(word); |
3710 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { | 3750 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { |
3711 m_syntaxParser.RestorePos(SavedPos); | 3751 m_syntaxParser.RestorePos(SavedPos); |
3712 return NULL; | 3752 return NULL; |
3713 } | 3753 } |
3714 CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0); | 3754 CPDF_Object* pObj = |
3755 m_syntaxParser.GetObject(pObjList, parser_objnum, gennum, 0); | |
3715 m_syntaxParser.RestorePos(SavedPos); | 3756 m_syntaxParser.RestorePos(SavedPos); |
3716 return pObj; | 3757 return pObj; |
3717 } | 3758 } |
3718 int32_t CPDF_DataAvail::IsLinearizedPDF() { | 3759 int32_t CPDF_DataAvail::IsLinearizedPDF() { |
3719 FX_DWORD req_size = 1024; | 3760 FX_DWORD req_size = 1024; |
3720 if (!m_pFileAvail->IsDataAvail(0, req_size)) { | 3761 if (!m_pFileAvail->IsDataAvail(0, req_size)) { |
3721 return PDF_UNKNOW_LINEARIZED; | 3762 return PDF_LINEARIZATION_UNKNOWN; |
3722 } | 3763 } |
3723 if (!m_pFileRead) { | 3764 if (!m_pFileRead) { |
3724 return PDF_NOT_LINEARIZED; | 3765 return PDF_NOT_LINEARIZED; |
3725 } | 3766 } |
3726 FX_FILESIZE dwSize = m_pFileRead->GetSize(); | 3767 FX_FILESIZE dwSize = m_pFileRead->GetSize(); |
3727 if (dwSize < (FX_FILESIZE)req_size) { | 3768 if (dwSize < (FX_FILESIZE)req_size) { |
3728 return PDF_UNKNOW_LINEARIZED; | 3769 return PDF_LINEARIZATION_UNKNOWN; |
3729 } | 3770 } |
3730 uint8_t buffer[1024]; | 3771 uint8_t buffer[1024]; |
3731 m_pFileRead->ReadBlock(buffer, 0, req_size); | 3772 m_pFileRead->ReadBlock(buffer, 0, req_size); |
3732 if (IsLinearizedFile(buffer, req_size)) { | 3773 if (IsLinearizedFile(buffer, req_size)) { |
3733 return PDF_IS_LINEARIZED; | 3774 return PDF_LINEARIZED; |
3734 } | 3775 } |
3735 return PDF_NOT_LINEARIZED; | 3776 return PDF_NOT_LINEARIZED; |
3736 } | 3777 } |
3737 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { | 3778 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { |
3738 CFX_SmartPointer<IFX_FileStream> file( | 3779 CFX_SmartPointer<IFX_FileStream> file( |
3739 FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); | 3780 FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); |
3740 int32_t offset = GetHeaderOffset(file.Get()); | 3781 int32_t offset = GetHeaderOffset(file.Get()); |
3741 if (offset == -1) { | 3782 if (offset == -1) { |
3742 m_docStatus = PDF_DATAAVAIL_ERROR; | 3783 m_docStatus = PDF_DATAAVAIL_ERROR; |
3743 return FALSE; | 3784 return FALSE; |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4462 return TRUE; | 4503 return TRUE; |
4463 } | 4504 } |
4464 if (m_bLinearized) { | 4505 if (m_bLinearized) { |
4465 if ((FX_DWORD)iPage == m_dwFirstPageNo) { | 4506 if ((FX_DWORD)iPage == m_dwFirstPageNo) { |
4466 m_pagesLoadState.insert(iPage); | 4507 m_pagesLoadState.insert(iPage); |
4467 return TRUE; | 4508 return TRUE; |
4468 } | 4509 } |
4469 if (!CheckLinearizedData(pHints)) { | 4510 if (!CheckLinearizedData(pHints)) { |
4470 return FALSE; | 4511 return FALSE; |
4471 } | 4512 } |
4513 if (m_pHintTables) { | |
4514 if (!m_pHintTables->CheckPage(iPage, pHints)) | |
4515 return FALSE; | |
4516 m_pagesLoadState.insert(iPage); | |
4517 return TRUE; | |
4518 } | |
4472 if (m_bMainXRefLoadedOK) { | 4519 if (m_bMainXRefLoadedOK) { |
4473 if (m_bTotalLoadPageTree) { | 4520 if (m_bTotalLoadPageTree) { |
4474 if (!LoadPages(pHints)) { | 4521 if (!LoadPages(pHints)) { |
4475 return FALSE; | 4522 return FALSE; |
4476 } | 4523 } |
4477 } else { | 4524 } else { |
4478 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { | 4525 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { |
4479 return FALSE; | 4526 return FALSE; |
4480 } | 4527 } |
4481 } | 4528 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4582 } | 4629 } |
4583 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, | 4630 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, |
4584 FX_DWORD* pSize) { | 4631 FX_DWORD* pSize) { |
4585 if (pPos) { | 4632 if (pPos) { |
4586 *pPos = m_dwLastXRefOffset; | 4633 *pPos = m_dwLastXRefOffset; |
4587 } | 4634 } |
4588 if (pSize) { | 4635 if (pSize) { |
4589 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); | 4636 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); |
4590 } | 4637 } |
4591 } | 4638 } |
4639 int CPDF_DataAvail::GetPageCount() const { | |
4640 if (!m_pDocument && !m_pLinearized) { | |
4641 return 0; | |
4642 } | |
4643 if (m_pLinearized) { | |
4644 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); | |
4645 CPDF_Object* pObj = pDict ? pDict->GetElementValue(FX_BSTRC("N")) : nullptr; | |
4646 return pObj ? pObj->GetInteger() : 0; | |
4647 } | |
4648 return m_pDocument->GetPageCount(); | |
yali_he
2015/10/19 13:24:35
retrun m_pDocument ? m_pDocument->GetPageCount() :
| |
4649 } | |
4650 CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) { | |
4651 if (!m_pDocument || index < 0 || index >= this->GetPageCount()) { | |
4652 return nullptr; | |
4653 } | |
4654 if (m_pLinearized) { | |
4655 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); | |
4656 CPDF_Object* pObj = pDict ? pDict->GetElementValue(FX_BSTRC("P")) : nullptr; | |
4657 int pageNum = pObj ? pObj->GetInteger() : 0; | |
4658 if (m_pHintTables && index != pageNum) { | |
4659 FX_FILESIZE szPageStartPos = 0; | |
4660 FX_FILESIZE szPageLength = 0; | |
4661 FX_DWORD dwObjNum = 0; | |
4662 FX_BOOL bPagePosGot = m_pHintTables->GetPagePos(index, szPageStartPos, | |
4663 szPageLength, dwObjNum); | |
4664 if (!bPagePosGot) { | |
4665 return nullptr; | |
4666 } | |
4667 m_syntaxParser.InitParser(m_pFileRead, (FX_DWORD)szPageStartPos); | |
4668 CPDF_Object* pPageDict = ParseIndirectObjectAt(0, dwObjNum, m_pDocument); | |
4669 if (!pPageDict) { | |
4670 return nullptr; | |
4671 } | |
4672 m_pDocument->InsertIndirectObject(dwObjNum, pPageDict); | |
4673 return pPageDict->GetDict(); | |
4674 } | |
4675 } | |
4676 return m_pDocument->GetPage(index); | |
4677 } | |
4592 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) { | 4678 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) { |
4593 if (!m_pDocument) { | 4679 if (!m_pDocument) { |
4594 return PDFFORM_AVAIL; | 4680 return PDF_FORM_AVAIL; |
4595 } | 4681 } |
4596 if (!m_bLinearizedFormParamLoad) { | 4682 if (!m_bLinearizedFormParamLoad) { |
4597 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); | 4683 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); |
4598 if (!pRoot) { | 4684 if (!pRoot) { |
4599 return PDFFORM_AVAIL; | 4685 return PDF_FORM_AVAIL; |
4600 } | 4686 } |
4601 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); | 4687 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); |
4602 if (!pAcroForm) { | 4688 if (!pAcroForm) { |
4603 return PDFFORM_NOTEXIST; | 4689 return PDF_FORM_NOTEXIST; |
4604 } | 4690 } |
4605 if (!CheckLinearizedData(pHints)) { | 4691 if (!CheckLinearizedData(pHints)) { |
4606 return PDFFORM_NOTAVAIL; | 4692 return PDF_FORM_NOTAVAIL; |
4607 } | 4693 } |
4608 if (!m_objs_array.GetSize()) { | 4694 if (!m_objs_array.GetSize()) { |
4609 m_objs_array.Add(pAcroForm->GetDict()); | 4695 m_objs_array.Add(pAcroForm->GetDict()); |
4610 } | 4696 } |
4611 m_bLinearizedFormParamLoad = TRUE; | 4697 m_bLinearizedFormParamLoad = TRUE; |
4612 } | 4698 } |
4613 CFX_PtrArray new_objs_array; | 4699 CFX_PtrArray new_objs_array; |
4614 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); | 4700 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); |
4615 m_objs_array.RemoveAll(); | 4701 m_objs_array.RemoveAll(); |
4616 if (!bRet) { | 4702 if (!bRet) { |
4617 m_objs_array.Append(new_objs_array); | 4703 m_objs_array.Append(new_objs_array); |
4618 return PDFFORM_NOTAVAIL; | 4704 return PDF_FORM_NOTAVAIL; |
4619 } | 4705 } |
4620 return PDFFORM_AVAIL; | 4706 return PDF_FORM_AVAIL; |
4621 } | 4707 } |
4622 void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) { | 4708 void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) { |
4623 int32_t iNext = 0; | 4709 int32_t iNext = 0; |
4624 if (BinarySearch(dwObjNum, iNext)) { | 4710 if (BinarySearch(dwObjNum, iNext)) { |
4625 return; | 4711 return; |
4626 } | 4712 } |
4627 m_number_array.InsertAt(iNext, dwObjNum); | 4713 m_number_array.InsertAt(iNext, dwObjNum); |
4628 } | 4714 } |
4629 FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) { | 4715 FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) { |
4630 int32_t iNext = 0; | 4716 int32_t iNext = 0; |
(...skipping 18 matching lines...) Expand all Loading... | |
4649 return FALSE; | 4735 return FALSE; |
4650 } | 4736 } |
4651 CPDF_PageNode::~CPDF_PageNode() { | 4737 CPDF_PageNode::~CPDF_PageNode() { |
4652 int32_t iSize = m_childNode.GetSize(); | 4738 int32_t iSize = m_childNode.GetSize(); |
4653 for (int32_t i = 0; i < iSize; ++i) { | 4739 for (int32_t i = 0; i < iSize; ++i) { |
4654 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; | 4740 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; |
4655 delete pNode; | 4741 delete pNode; |
4656 } | 4742 } |
4657 m_childNode.RemoveAll(); | 4743 m_childNode.RemoveAll(); |
4658 } | 4744 } |
4745 CPDF_HintTables::~CPDF_HintTables() { | |
4746 m_nFirstPageSharedObjs = 0; | |
Tom Sepez
2015/10/14 16:57:45
These assignments are usually pointless in a dtor.
jun_fang
2015/10/15 10:22:28
Acknowledged.
| |
4747 m_szFirstPageObjOffset = 0; | |
4748 m_dwDeltaNObjsArray.RemoveAll(); | |
4749 m_dwNSharedObjsArray.RemoveAll(); | |
4750 m_dwSharedObjNumArray.RemoveAll(); | |
4751 m_dwIdentifierArray.RemoveAll(); | |
4752 m_szPageOffsetArray.RemoveAll(); | |
4753 m_szSharedObjOffsetArray.RemoveAll(); | |
4754 } | |
4755 FX_DWORD CPDF_HintTables::GetItemLength(int index, | |
4756 const CFX_FileSizeArray& szArray) { | |
4757 if (index < 0 || index > szArray.GetSize() - 2) | |
Tom Sepez
2015/10/14 16:57:45
szArray.GetSize() - 2 would underflow if it were e
jun_fang
2015/10/15 10:22:28
Acknowledged.
| |
4758 return 0; | |
4759 return szArray[index + 1] - szArray[index]; | |
yali_he
2015/10/19 13:24:35
szArray[index + 1] must be larger than szArray[ind
| |
4760 } | |
4761 FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { | |
4762 if (!hStream) | |
4763 return FALSE; | |
4764 int nStreamOffset = ReadPrimaryHintStreamOffset(); | |
4765 int nStreamLen = ReadPrimaryHintStreamLength(); | |
4766 if (nStreamOffset < 0 || nStreamLen < 1) | |
4767 return FALSE; | |
4768 // Item 1: The least number of objects in a page. | |
4769 FX_DWORD dwObjLeastNum = hStream->GetBits(32); | |
4770 // Item 2: The location of the first page's page object. | |
4771 FX_DWORD dwFirstObjLoc = hStream->GetBits(32); | |
4772 if (dwFirstObjLoc > nStreamOffset) { | |
4773 FX_SAFE_DWORD safeLoc = pdfium::base::checked_cast<FX_DWORD>(nStreamLen); | |
4774 safeLoc += dwFirstObjLoc; | |
4775 if (!safeLoc.IsValid()) | |
4776 return FALSE; | |
4777 m_szFirstPageObjOffset = | |
4778 pdfium::base::checked_cast<FX_FILESIZE>(safeLoc.ValueOrDie()); | |
4779 } else { | |
4780 m_szFirstPageObjOffset = | |
4781 pdfium::base::checked_cast<FX_FILESIZE>(dwFirstObjLoc); | |
4782 } | |
4783 // Item 3: The number of bits needed to represent the difference | |
4784 // between the greatest and least number of objects in a page. | |
4785 FX_DWORD dwDeltaObjectsBits = hStream->GetBits(16); | |
4786 // Item 4: The least length of a page in bytes. | |
4787 FX_DWORD dwPageLeastLen = hStream->GetBits(32); | |
4788 // Item 5: The number of bits needed to represent the difference | |
4789 // between the greatest and least length of a page, in bytes. | |
4790 FX_DWORD dwDeltaPageLenBits = hStream->GetBits(16); | |
4791 // Skip Item 6, 7, 8, 9 total 96 bits. | |
4792 hStream->SkipBits(96); | |
4793 // Item 10: The number of bits needed to represent the greatest | |
4794 // number of shared object references. | |
4795 FX_DWORD dwSharedObjBits = hStream->GetBits(16); | |
4796 // Item 11: The number of bits needed to represent the numerically | |
4797 // greatest shared object identifier used by the pages. | |
4798 FX_DWORD dwSharedIdBits = hStream->GetBits(16); | |
4799 // Item 12: The number of bits needed to represent the numerator of | |
4800 // the fractional position for each shared object reference. For each | |
4801 // shared object referenced from a page, there is an indication of | |
4802 // where in the page's content stream the object is first referenced. | |
4803 FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16); | |
4804 // Item 13: Skip Item 13 which has 16 bits. | |
4805 FX_DWORD dwSharedDenominator = hStream->GetBits(16); | |
4806 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N")); | |
4807 int nPages = pPageNum ? pPageNum->GetInteger() : 0; | |
4808 if (nPages < 1) | |
4809 return FALSE; | |
4810 for (int i = 0; i < nPages; ++i) { | |
4811 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); | |
4812 safeDeltaObj += dwObjLeastNum; | |
4813 if (!safeDeltaObj.IsValid()) | |
4814 return FALSE; | |
4815 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); | |
4816 } | |
4817 hStream->ByteAlign(); | |
4818 CFX_DWordArray dwPageLenArray; | |
4819 for (int i = 0; i < nPages; ++i) { | |
4820 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); | |
4821 safePageLen += dwPageLeastLen; | |
4822 if (!safePageLen.IsValid()) | |
4823 return FALSE; | |
4824 dwPageLenArray.Add(safePageLen.ValueOrDie()); | |
4825 } | |
4826 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E")); | |
4827 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1; | |
4828 if (nOffsetE < 0) | |
4829 return FALSE; | |
4830 CPDF_Object* pFirstPageNum = | |
4831 m_pLinearizedDict->GetElementValue(FX_BSTRC("P")); | |
4832 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; | |
4833 for (int i = 0; i < nPages; ++i) { | |
4834 if (i == nFirstPageNum) { | |
4835 m_szPageOffsetArray.Add(m_szFirstPageObjOffset); | |
4836 } else if (i == nFirstPageNum + 1) { | |
4837 if (i == 1) { | |
4838 m_szPageOffsetArray.Add(nOffsetE); | |
4839 } else { | |
4840 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 2] + | |
4841 dwPageLenArray[i - 2]); | |
4842 } | |
4843 } else { | |
4844 if (i == 0) { | |
4845 m_szPageOffsetArray.Add(nOffsetE); | |
4846 } else { | |
4847 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 1] + | |
4848 dwPageLenArray[i - 1]); | |
4849 } | |
4850 } | |
4851 } | |
4852 if (nPages > 0) { | |
4853 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] + | |
4854 dwPageLenArray[nPages - 1]); | |
4855 } | |
4856 hStream->ByteAlign(); | |
4857 // number of shared objects | |
4858 for (int i = 0; i < nPages; i++) { | |
4859 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); | |
4860 } | |
4861 hStream->ByteAlign(); | |
4862 // array of identifier, sizes = nshared_objects | |
4863 for (int i = 0; i < nPages; i++) { | |
4864 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) { | |
4865 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); | |
4866 } | |
4867 } | |
4868 hStream->ByteAlign(); | |
4869 for (int i = 0; i < nPages; i++) { | |
4870 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; | |
4871 safeSize *= dwSharedNumeratorBits; | |
4872 if (!safeSize.IsValid()) | |
4873 return FALSE; | |
4874 hStream->SkipBits(safeSize.ValueOrDie()); | |
4875 } | |
4876 hStream->ByteAlign(); | |
4877 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); | |
4878 safeTotalPageLen *= dwDeltaPageLenBits; | |
4879 if (!safeTotalPageLen.IsValid()) | |
4880 return FALSE; | |
4881 hStream->SkipBits(safeTotalPageLen.ValueOrDie()); | |
4882 hStream->ByteAlign(); | |
4883 return TRUE; | |
4884 } | |
4885 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream) { | |
4886 if (!hStream) | |
4887 return FALSE; | |
4888 int nStreamOffset = ReadPrimaryHintStreamOffset(); | |
4889 int nStreamLen = ReadPrimaryHintStreamLength(); | |
4890 if (nStreamOffset < 0 || nStreamLen < 1) | |
4891 return FALSE; | |
4892 // Item 1: The object number of the first object in the shared objects | |
4893 // section. | |
4894 FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32); | |
4895 // Item 2: The location of the first object in the shared objects section. | |
4896 FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32); | |
4897 if (dwFirstSharedObjLoc > nStreamOffset) | |
4898 dwFirstSharedObjLoc += nStreamLen; | |
4899 // Item 3: The number of shared object entries for the first page. | |
4900 m_nFirstPageSharedObjs = hStream->GetBits(32); | |
4901 // Item 4: The number of shared object entries for the shared objects | |
4902 // section, including the number of shared object entries for the first page. | |
4903 FX_DWORD dwSharedObjTotal = hStream->GetBits(32); | |
4904 // Item 5: The number of bits needed to represent the greatest number of | |
4905 // objects in a shared object group. Skipped. | |
4906 hStream->SkipBits(16); | |
4907 // Item 6: The least length of a shared object group in bytes. | |
4908 FX_DWORD dwGroupLeastLen = hStream->GetBits(32); | |
4909 // Item 7: The number of bits needed to represent the difference between the | |
4910 // greatest and least length of a shared object group, in bytes. | |
4911 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); | |
4912 CPDF_Object* pFirstPageObj = | |
4913 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); | |
4914 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; | |
4915 if (nFirstPageObjNum < 0) | |
4916 return FALSE; | |
4917 FX_DWORD dwPrevObjLen = 0; | |
4918 FX_DWORD dwCurObjLen = 0; | |
4919 for (int i = 0; i < dwSharedObjTotal; ++i) { | |
4920 dwPrevObjLen = dwCurObjLen; | |
4921 FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen); | |
4922 safeObjLen += dwGroupLeastLen; | |
4923 if (!safeObjLen.IsValid()) | |
4924 return FALSE; | |
4925 dwCurObjLen = safeObjLen.ValueOrDie(); | |
4926 if (i < m_nFirstPageSharedObjs) { | |
4927 m_dwSharedObjNumArray.Add(nFirstPageObjNum + i); | |
4928 if (i == 0) | |
4929 m_szSharedObjOffsetArray.Add(m_szFirstPageObjOffset); | |
4930 } else { | |
4931 FX_SAFE_DWORD safeObjNum = dwFirstSharedObjNum; | |
4932 safeObjNum += i - m_nFirstPageSharedObjs; | |
4933 if (safeObjNum.IsValid()) | |
4934 return FALSE; | |
4935 m_dwSharedObjNumArray.Add(safeObjNum.ValueOrDie()); | |
4936 if (i == m_nFirstPageSharedObjs) | |
4937 m_szSharedObjOffsetArray.Add( | |
4938 pdfium::base::checked_cast<int32_t>(dwFirstSharedObjLoc)); | |
4939 } | |
4940 if (i != 0 && i != m_nFirstPageSharedObjs) { | |
4941 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwPrevObjLen); | |
4942 safeLoc += m_szSharedObjOffsetArray[i - 1]; | |
4943 if (!safeLoc.IsValid()) | |
4944 return FALSE; | |
4945 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie()); | |
4946 } | |
4947 } | |
4948 if (dwSharedObjTotal > 0) { | |
4949 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwCurObjLen); | |
4950 safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1]; | |
4951 if (!safeLoc.IsValid()) | |
4952 return FALSE; | |
4953 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie()); | |
4954 } | |
4955 hStream->ByteAlign(); | |
4956 hStream->SkipBits(dwSharedObjTotal); | |
4957 hStream->ByteAlign(); | |
4958 return TRUE; | |
4959 } | |
4960 FX_BOOL CPDF_HintTables::GetPagePos(int index, | |
4961 FX_FILESIZE& szPageStartPos, | |
4962 FX_FILESIZE& szPageLength, | |
4963 FX_DWORD& dwObjNum) { | |
4964 if (!m_pLinearizedDict) | |
4965 return FALSE; | |
4966 szPageStartPos = m_szPageOffsetArray[index]; | |
4967 szPageLength = GetItemLength(index, m_szPageOffsetArray); | |
4968 CPDF_Object* pFirstPageNum = | |
4969 m_pLinearizedDict->GetElementValue(FX_BSTRC("P")); | |
4970 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; | |
4971 CPDF_Object* pFirstPageObjNum = | |
4972 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); | |
4973 if (!pFirstPageObjNum) | |
4974 return FALSE; | |
4975 int nFirstPageObjNum = pFirstPageObjNum->GetInteger(); | |
4976 if (index == nFirstPageNum) { | |
4977 dwObjNum = nFirstPageObjNum; | |
4978 return TRUE; | |
4979 } | |
4980 // The object number of remaining pages starts from 1. | |
4981 dwObjNum = 1; | |
4982 for (int i = 0; i < index; ++i) { | |
4983 if (i == nFirstPageNum) | |
4984 continue; | |
4985 dwObjNum += m_dwDeltaNObjsArray[i]; | |
4986 } | |
4987 return TRUE; | |
4988 } | |
4989 FX_BOOL CPDF_HintTables::CheckPage(int index, IFX_DownloadHints* pHints) { | |
4990 if (!m_pLinearizedDict) | |
4991 return FALSE; | |
4992 CPDF_Object* pFirstAvailPage = | |
4993 m_pLinearizedDict->GetElementValue(FX_BSTRC("P")); | |
4994 int nFirstAvailPage = pFirstAvailPage ? pFirstAvailPage->GetInteger() : 0; | |
4995 if (index == nFirstAvailPage) | |
4996 return TRUE; | |
4997 FX_DWORD dwLength = GetItemLength(index, m_szPageOffsetArray); | |
4998 if (!dwLength || | |
4999 !m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength, | |
5000 pHints)) { | |
5001 return FALSE; | |
5002 } | |
5003 // Download data of shared objects in the page. | |
5004 FX_DWORD offset = 0; | |
5005 for (int i = 0; i < index; ++i) { | |
5006 offset += m_dwNSharedObjsArray[i]; | |
5007 } | |
5008 CPDF_Object* pFirstPageObj = | |
5009 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); | |
5010 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; | |
5011 if (nFirstPageObjNum < 0) | |
5012 return FALSE; | |
5013 FX_DWORD dwIndex = 0; | |
5014 FX_DWORD dwObjNum = 0; | |
5015 for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) { | |
5016 dwIndex = m_dwIdentifierArray[offset + j]; | |
5017 dwObjNum = m_dwSharedObjNumArray[dwIndex]; | |
5018 if (dwObjNum >= nFirstPageObjNum && | |
5019 dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) { | |
5020 continue; | |
5021 } | |
5022 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray); | |
5023 if (!dwLength || | |
5024 !m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, | |
5025 pHints)) { | |
5026 return FALSE; | |
5027 } | |
5028 } | |
5029 return TRUE; | |
5030 } | |
5031 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { | |
5032 if (!pHintStream || !m_pLinearizedDict) | |
5033 return FALSE; | |
5034 CPDF_Dictionary* pDict = pHintStream->GetDict(); | |
5035 CPDF_Object* pOffset = pDict ? pDict->GetElement(FX_BSTRC("S")) : nullptr; | |
5036 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER) | |
5037 return FALSE; | |
5038 CPDF_StreamAcc acc; | |
5039 acc.LoadAllData(pHintStream); | |
5040 FX_DWORD size = acc.GetSize(); | |
5041 // The header section of page offset hint table is 36 bytes. | |
5042 // The header section of shared object hint table is 24 bytes. | |
5043 // Hint table has at least 60 bytes. | |
5044 const FX_DWORD MIN_STREAM_LEN = 60; | |
5045 if (size < MIN_STREAM_LEN || size < pOffset->GetInteger() || | |
5046 !pOffset->GetInteger()) { | |
5047 return FALSE; | |
5048 } | |
5049 CFX_BitStream bs; | |
5050 bs.Init(acc.GetData(), size); | |
5051 return ReadPageHintTable(&bs) && ReadSharedObjHintTable(&bs); | |
5052 } | |
5053 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { | |
5054 if (!m_pLinearizedDict) | |
5055 return -1; | |
5056 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); | |
5057 if (!pRange) | |
5058 return -1; | |
5059 CPDF_Object* pStreamOffset = pRange->GetElementValue(0); | |
5060 if (!pStreamOffset) | |
5061 return -1; | |
5062 return pStreamOffset->GetInteger(); | |
5063 } | |
5064 int CPDF_HintTables::ReadPrimaryHintStreamLength() const { | |
5065 if (!m_pLinearizedDict) | |
5066 return -1; | |
5067 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); | |
5068 if (!pRange) | |
5069 return -1; | |
5070 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | |
5071 if (!pStreamLen) | |
5072 return -1; | |
5073 return pStreamLen->GetInteger(); | |
5074 } | |
OLD | NEW |