Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp

Issue 1366593002: Support linearized loading (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « core/include/fpdfapi/fpdf_parser.h ('k') | core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698