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

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

Issue 1353093003: 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 "../../../../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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698