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

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, 3 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"
Tom Sepez 2015/09/22 00:05:38 nit: no ./
jun_fang 2015/09/22 12:42:31 Acknowledged.
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 2777 matching lines...) Expand 10 before | Expand all | Expand 10 after
2803 } 2804 }
2804 buffer[offset++] = ch; 2805 buffer[offset++] = ch;
2805 if (offset == size) { 2806 if (offset == size) {
2806 break; 2807 break;
2807 } 2808 }
2808 } 2809 }
2809 } 2810 }
2810 2811
2811 class CPDF_DataAvail final : public IPDF_DataAvail { 2812 class CPDF_DataAvail final : public IPDF_DataAvail {
2812 public: 2813 public:
2813 CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); 2814 CPDF_DataAvail(IFX_FileAvail* pFileAvail,
2815 IFX_FileRead* pFileRead,
2816 FX_BOOL bSupportHintTable = FALSE);
2814 ~CPDF_DataAvail() override; 2817 ~CPDF_DataAvail() override;
2815 2818
2816 virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; 2819 virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override;
2817 2820
2818 virtual void SetDocument(CPDF_Document* pDoc) override; 2821 virtual void SetDocument(CPDF_Document* pDoc) override;
2819 2822
2820 virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; 2823 virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override;
2821 2824
2822 virtual int32_t IsFormAvail(IFX_DownloadHints* pHints) override; 2825 virtual int32_t IsFormAvail(IFX_DownloadHints* pHints) override;
2823 2826
2824 virtual int32_t IsLinearizedPDF() override; 2827 virtual int32_t IsLinearizedPDF() override;
2825 2828
2826 virtual FX_BOOL IsLinearized() override { return m_bLinearized; } 2829 virtual FX_BOOL IsLinearized() override { return m_bLinearized; }
2827 2830
2828 virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, 2831 virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos,
2829 FX_DWORD* pSize) override; 2832 FX_DWORD* pSize) override;
2833 int GetPageCount() const;
2834 CPDF_Dictionary* GetPage(int index);
2830 2835
2831 protected: 2836 protected:
2832 static const int kMaxDataAvailRecursionDepth = 64; 2837 static const int kMaxDataAvailRecursionDepth = 64;
2833 static int s_CurrentDataAvailRecursionDepth; 2838 static int s_CurrentDataAvailRecursionDepth;
2834 2839
2835 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); 2840 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset);
2836 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, 2841 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array,
2837 FX_BOOL bParsePage, 2842 FX_BOOL bParsePage,
2838 IFX_DownloadHints* pHints, 2843 IFX_DownloadHints* pHints,
2839 CFX_PtrArray& ret_array); 2844 CFX_PtrArray& ret_array);
2840 FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints); 2845 FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints);
2841 FX_BOOL CheckHeader(IFX_DownloadHints* pHints); 2846 FX_BOOL CheckHeader(IFX_DownloadHints* pHints);
2842 FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints); 2847 FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints);
2848 FX_BOOL CheckHintTables(IFX_DownloadHints* pHints);
2843 FX_BOOL CheckEnd(IFX_DownloadHints* pHints); 2849 FX_BOOL CheckEnd(IFX_DownloadHints* pHints);
2844 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); 2850 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints);
2845 FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints); 2851 FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints);
2846 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); 2852 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints);
2847 FX_BOOL CheckRoot(IFX_DownloadHints* pHints); 2853 FX_BOOL CheckRoot(IFX_DownloadHints* pHints);
2848 FX_BOOL CheckInfo(IFX_DownloadHints* pHints); 2854 FX_BOOL CheckInfo(IFX_DownloadHints* pHints);
2849 FX_BOOL CheckPages(IFX_DownloadHints* pHints); 2855 FX_BOOL CheckPages(IFX_DownloadHints* pHints);
2850 FX_BOOL CheckPage(IFX_DownloadHints* pHints); 2856 FX_BOOL CheckPage(IFX_DownloadHints* pHints);
2851 FX_BOOL CheckResources(IFX_DownloadHints* pHints); 2857 FX_BOOL CheckResources(IFX_DownloadHints* pHints);
2852 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); 2858 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints);
2853 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); 2859 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints);
2854 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); 2860 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints);
2855 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); 2861 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints);
2856 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); 2862 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints);
2857 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints); 2863 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints);
2858 2864
2859 int32_t CheckCrossRefStream(IFX_DownloadHints* pHints, 2865 int32_t CheckCrossRefStream(IFX_DownloadHints* pHints,
2860 FX_FILESIZE& xref_offset); 2866 FX_FILESIZE& xref_offset);
2861 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); 2867 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen);
2862 void SetStartOffset(FX_FILESIZE dwOffset); 2868 void SetStartOffset(FX_FILESIZE dwOffset);
2863 FX_BOOL GetNextToken(CFX_ByteString& token); 2869 FX_BOOL GetNextToken(CFX_ByteString& token);
2864 FX_BOOL GetNextChar(uint8_t& ch); 2870 FX_BOOL GetNextChar(uint8_t& ch);
2865 CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum); 2871 CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos,
2872 FX_DWORD objnum,
2873 CPDF_IndirectObjects* pObjList = NULL);
2866 CPDF_Object* GetObject(FX_DWORD objnum, 2874 CPDF_Object* GetObject(FX_DWORD objnum,
2867 IFX_DownloadHints* pHints, 2875 IFX_DownloadHints* pHints,
2868 FX_BOOL* pExistInFile); 2876 FX_BOOL* pExistInFile);
2869 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); 2877 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages);
2870 FX_BOOL PreparePageItem(); 2878 FX_BOOL PreparePageItem();
2871 FX_BOOL LoadPages(IFX_DownloadHints* pHints); 2879 FX_BOOL LoadPages(IFX_DownloadHints* pHints);
2872 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); 2880 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints);
2873 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); 2881 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints);
2874 FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); 2882 FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints);
2875 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); 2883 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints);
(...skipping 10 matching lines...) Expand all
2886 IFX_DownloadHints* pHints); 2894 IFX_DownloadHints* pHints);
2887 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, 2895 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo,
2888 CPDF_PageNode* pPageNode, 2896 CPDF_PageNode* pPageNode,
2889 IFX_DownloadHints* pHints); 2897 IFX_DownloadHints* pHints);
2890 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, 2898 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo,
2891 CPDF_PageNode* pPageNode, 2899 CPDF_PageNode* pPageNode,
2892 IFX_DownloadHints* pHints); 2900 IFX_DownloadHints* pHints);
2893 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); 2901 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints);
2894 FX_BOOL IsFirstCheck(int iPage); 2902 FX_BOOL IsFirstCheck(int iPage);
2895 void ResetFirstCheck(int iPage); 2903 void ResetFirstCheck(int iPage);
2904 FX_BOOL IsDataAvail(FX_FILESIZE offset,
2905 FX_DWORD size,
2906 IFX_DownloadHints* pHints);
2896 2907
2897 CPDF_Parser m_parser; 2908 CPDF_Parser m_parser;
2898 2909
2899 CPDF_SyntaxParser m_syntaxParser; 2910 CPDF_SyntaxParser m_syntaxParser;
2900 2911
2901 CPDF_Object* m_pRoot; 2912 CPDF_Object* m_pRoot;
2902 2913
2903 FX_DWORD m_dwRootObjNum; 2914 FX_DWORD m_dwRootObjNum;
2904 2915
2905 FX_DWORD m_dwInfoObjNum; 2916 FX_DWORD m_dwInfoObjNum;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2999 FX_FILESIZE m_dwPrevXRefOffset; 3010 FX_FILESIZE m_dwPrevXRefOffset;
3000 3011
3001 FX_BOOL m_bTotalLoadPageTree; 3012 FX_BOOL m_bTotalLoadPageTree;
3002 3013
3003 FX_BOOL m_bCurPageDictLoadOK; 3014 FX_BOOL m_bCurPageDictLoadOK;
3004 3015
3005 CPDF_PageNode m_pageNodes; 3016 CPDF_PageNode m_pageNodes;
3006 3017
3007 std::set<FX_DWORD> m_pageMapCheckState; 3018 std::set<FX_DWORD> m_pageMapCheckState;
3008 std::set<FX_DWORD> m_pagesLoadState; 3019 std::set<FX_DWORD> m_pagesLoadState;
3020
3021 CPDF_HintTables* m_pHintTables;
3022 FX_BOOL m_bSupportHintTable;
3023
3024 public:
3025 friend class CPDF_HintTables;
Tom Sepez 2015/09/22 00:05:38 nit: we'd be happier if you added the correspondin
3009 }; 3026 };
3010 3027
3011 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, 3028 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail,
3012 IFX_FileRead* pFileRead) 3029 IFX_FileRead* pFileRead)
3013 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} 3030 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {
3031 }
3014 3032
3015 // static 3033 // static
3016 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, 3034 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail,
3017 IFX_FileRead* pFileRead) { 3035 IFX_FileRead* pFileRead) {
3018 return new CPDF_DataAvail(pFileAvail, pFileRead); 3036 return new CPDF_DataAvail(pFileAvail, pFileRead);
3019 } 3037 }
3020 3038
3021 // static 3039 // static
3022 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; 3040 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0;
3023 3041
3024 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, 3042 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail,
3025 IFX_FileRead* pFileRead) 3043 IFX_FileRead* pFileRead,
3044 FX_BOOL bSupportHintTable)
3026 : IPDF_DataAvail(pFileAvail, pFileRead) { 3045 : IPDF_DataAvail(pFileAvail, pFileRead) {
3027 m_Pos = 0; 3046 m_Pos = 0;
3028 m_dwFileLen = 0; 3047 m_dwFileLen = 0;
3029 if (m_pFileRead) { 3048 if (m_pFileRead) {
3030 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); 3049 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
3031 } 3050 }
3032 m_dwCurrentOffset = 0; 3051 m_dwCurrentOffset = 0;
3033 m_WordSize = 0; 3052 m_WordSize = 0;
3034 m_dwXRefOffset = 0; 3053 m_dwXRefOffset = 0;
3035 m_bufferOffset = 0; 3054 m_bufferOffset = 0;
(...skipping 25 matching lines...) Expand all
3061 m_pTrailer = NULL; 3080 m_pTrailer = NULL;
3062 m_pCurrentParser = NULL; 3081 m_pCurrentParser = NULL;
3063 m_pAcroForm = NULL; 3082 m_pAcroForm = NULL;
3064 m_pPageDict = NULL; 3083 m_pPageDict = NULL;
3065 m_pPageResource = NULL; 3084 m_pPageResource = NULL;
3066 m_docStatus = PDF_DATAAVAIL_HEADER; 3085 m_docStatus = PDF_DATAAVAIL_HEADER;
3067 m_parser.m_bOwnFileRead = FALSE; 3086 m_parser.m_bOwnFileRead = FALSE;
3068 m_bTotalLoadPageTree = FALSE; 3087 m_bTotalLoadPageTree = FALSE;
3069 m_bCurPageDictLoadOK = FALSE; 3088 m_bCurPageDictLoadOK = FALSE;
3070 m_bLinearedDataOK = FALSE; 3089 m_bLinearedDataOK = FALSE;
3090 m_pHintTables = NULL;
3091 m_bSupportHintTable = bSupportHintTable;
3071 } 3092 }
3072 CPDF_DataAvail::~CPDF_DataAvail() { 3093 CPDF_DataAvail::~CPDF_DataAvail() {
3073 if (m_pLinearized) { 3094 if (m_pLinearized) {
3074 m_pLinearized->Release(); 3095 m_pLinearized->Release();
3075 } 3096 }
3076 if (m_pRoot) { 3097 if (m_pRoot) {
3077 m_pRoot->Release(); 3098 m_pRoot->Release();
3078 } 3099 }
3079 if (m_pTrailer) { 3100 if (m_pTrailer) {
3080 m_pTrailer->Release(); 3101 m_pTrailer->Release();
3081 } 3102 }
3103 if (m_pHintTables) {
Tom Sepez 2015/09/22 00:05:38 nit: just delete m_pHintables. There's no need to
jun_fang 2015/09/22 12:42:32 Acknowledged.
3104 delete m_pHintTables;
Tom Sepez 2015/09/22 00:05:39 if CPDF_DataAvail owns these hint tables, then use
3105 }
3082 int32_t i = 0; 3106 int32_t i = 0;
3083 int32_t iSize = m_arrayAcroforms.GetSize(); 3107 int32_t iSize = m_arrayAcroforms.GetSize();
3084 for (i = 0; i < iSize; ++i) { 3108 for (i = 0; i < iSize; ++i) {
3085 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release(); 3109 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release();
3086 } 3110 }
3087 } 3111 }
3088 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { 3112 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) {
3089 m_pDocument = pDoc; 3113 m_pDocument = pDoc;
3090 } 3114 }
3091 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { 3115 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
3156 value = pDict->GetNextElement(pos, key); 3180 value = pDict->GetNextElement(pos, key);
3157 if (key != "Parent") { 3181 if (key != "Parent") {
3158 new_obj_array.Add(value); 3182 new_obj_array.Add(value);
3159 } 3183 }
3160 } 3184 }
3161 } break; 3185 } break;
3162 case PDFOBJ_REFERENCE: { 3186 case PDFOBJ_REFERENCE: {
3163 CPDF_Reference* pRef = (CPDF_Reference*)pObj; 3187 CPDF_Reference* pRef = (CPDF_Reference*)pObj;
3164 FX_DWORD dwNum = pRef->GetRefObjNum(); 3188 FX_DWORD dwNum = pRef->GetRefObjNum();
3165 FX_FILESIZE offset; 3189 FX_FILESIZE offset;
3166 FX_DWORD original_size = GetObjectSize(dwNum, offset); 3190 FX_DWORD size = GetObjectSize(dwNum, offset);
3167 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; 3191 if (size == 0 || offset < 0 || offset >= m_dwFileLen) {
3168 if (size.ValueOrDefault(0) == 0 || offset < 0 ||
3169 offset >= m_dwFileLen) {
3170 break; 3192 break;
3171 } 3193 }
3172 3194 if (!IsDataAvail(offset, size, pHints)) {
3173 size += offset;
3174 size += 512;
3175 if (!size.IsValid()) {
3176 break;
3177 }
3178 if (size.ValueOrDie() > m_dwFileLen) {
3179 size = m_dwFileLen - offset;
3180 } else {
3181 size = original_size + 512;
3182 }
3183 if (!size.IsValid()) {
3184 break;
3185 }
3186 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) {
3187 pHints->AddSegment(offset, size.ValueOrDie());
3188 ret_array.Add(pObj); 3195 ret_array.Add(pObj);
3189 count++; 3196 count++;
3190 } else if (!m_objnum_array.Find(dwNum)) { 3197 } else if (!m_objnum_array.Find(dwNum)) {
3191 m_objnum_array.AddObjNum(dwNum); 3198 m_objnum_array.AddObjNum(dwNum);
3192 CPDF_Object* pReferred = 3199 CPDF_Object* pReferred =
3193 m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL); 3200 m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL);
3194 if (pReferred) { 3201 if (pReferred) {
3195 new_obj_array.Add(pReferred); 3202 new_obj_array.Add(pReferred);
3196 } 3203 }
3197 } 3204 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
3277 m_docStatus = PDF_DATAAVAIL_PAGETREE; 3284 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3278 return TRUE; 3285 return TRUE;
3279 } 3286 }
3280 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { 3287 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) {
3281 switch (m_docStatus) { 3288 switch (m_docStatus) {
3282 case PDF_DATAAVAIL_HEADER: 3289 case PDF_DATAAVAIL_HEADER:
3283 return CheckHeader(pHints); 3290 return CheckHeader(pHints);
3284 case PDF_DATAAVAIL_FIRSTPAGE: 3291 case PDF_DATAAVAIL_FIRSTPAGE:
3285 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: 3292 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE:
3286 return CheckFirstPage(pHints); 3293 return CheckFirstPage(pHints);
3294 case PDF_DATAAVAIL_HINTTABLE:
3295 return CheckHintTables(pHints);
3287 case PDF_DATAAVAIL_END: 3296 case PDF_DATAAVAIL_END:
3288 return CheckEnd(pHints); 3297 return CheckEnd(pHints);
3289 case PDF_DATAAVAIL_CROSSREF: 3298 case PDF_DATAAVAIL_CROSSREF:
3290 return CheckCrossRef(pHints); 3299 return CheckCrossRef(pHints);
3291 case PDF_DATAAVAIL_CROSSREF_ITEM: 3300 case PDF_DATAAVAIL_CROSSREF_ITEM:
3292 return CheckCrossRefItem(pHints); 3301 return CheckCrossRefItem(pHints);
3293 case PDF_DATAAVAIL_CROSSREF_STREAM: 3302 case PDF_DATAAVAIL_CROSSREF_STREAM:
3294 return CheckAllCrossRefStream(pHints); 3303 return CheckAllCrossRefStream(pHints);
3295 case PDF_DATAAVAIL_TRAILER: 3304 case PDF_DATAAVAIL_TRAILER:
3296 return CheckTrailer(pHints); 3305 return CheckTrailer(pHints);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
3361 _CompareFileSize); 3370 _CompareFileSize);
3362 m_dwRootObjNum = m_parser.GetRootObjNum(); 3371 m_dwRootObjNum = m_parser.GetRootObjNum();
3363 m_dwInfoObjNum = m_parser.GetInfoObjNum(); 3372 m_dwInfoObjNum = m_parser.GetInfoObjNum();
3364 m_pCurrentParser = &m_parser; 3373 m_pCurrentParser = &m_parser;
3365 m_docStatus = PDF_DATAAVAIL_ROOT; 3374 m_docStatus = PDF_DATAAVAIL_ROOT;
3366 return TRUE; 3375 return TRUE;
3367 } 3376 }
3368 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, 3377 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum,
3369 IFX_DownloadHints* pHints, 3378 IFX_DownloadHints* pHints,
3370 FX_BOOL* pExistInFile) { 3379 FX_BOOL* pExistInFile) {
3371 CPDF_Object* pRet = NULL; 3380 CPDF_Object* pRet = nullptr;
3372 FX_DWORD original_size = 0; 3381 FX_DWORD size = 0;
3373 FX_FILESIZE offset = 0; 3382 FX_FILESIZE offset = 0;
3374 CPDF_Parser* pParser = NULL; 3383 CPDF_Parser* pParser = nullptr;
3375 3384 if (pExistInFile)
3376 if (pExistInFile) {
3377 *pExistInFile = TRUE; 3385 *pExistInFile = TRUE;
3378 }
3379 3386
3380 if (m_pDocument == NULL) { 3387 if (m_pDocument == NULL) {
3381 original_size = (FX_DWORD)m_parser.GetObjectSize(objnum); 3388 size = (FX_DWORD)m_parser.GetObjectSize(objnum);
3382 offset = m_parser.GetObjectOffset(objnum); 3389 offset = m_parser.GetObjectOffset(objnum);
3383 pParser = &m_parser; 3390 pParser = &m_parser;
3384 } else { 3391 } else {
3385 original_size = GetObjectSize(objnum, offset); 3392 size = GetObjectSize(objnum, offset);
3386 pParser = (CPDF_Parser*)(m_pDocument->GetParser()); 3393 pParser = (CPDF_Parser*)(m_pDocument->GetParser());
3387 } 3394 }
3388 3395 if (!IsDataAvail(offset, size, pHints)) {
3389 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; 3396 return nullptr;
3390 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) { 3397 }
3391 if (pExistInFile)
3392 *pExistInFile = FALSE;
3393
3394 return NULL;
3395 }
3396
3397 size += offset;
3398 size += 512;
3399 if (!size.IsValid()) {
3400 return NULL;
3401 }
3402
3403 if (size.ValueOrDie() > m_dwFileLen) {
3404 size = m_dwFileLen - offset;
3405 } else {
3406 size = original_size + 512;
3407 }
3408
3409 if (!size.IsValid()) {
3410 return NULL;
3411 }
3412
3413 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) {
3414 pHints->AddSegment(offset, size.ValueOrDie());
3415 return NULL;
3416 }
3417
3418 if (pParser) { 3398 if (pParser) {
3419 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); 3399 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL);
3420 } 3400 }
3421
3422 if (!pRet && pExistInFile) { 3401 if (!pRet && pExistInFile) {
3423 *pExistInFile = FALSE; 3402 *pExistInFile = FALSE;
3424 } 3403 }
3425
3426 return pRet; 3404 return pRet;
3427 } 3405 }
3428
3429 FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) { 3406 FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) {
3430 FX_BOOL bExist = FALSE; 3407 FX_BOOL bExist = FALSE;
3431 CPDF_Object* pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist); 3408 CPDF_Object* pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist);
3432 if (!bExist) { 3409 if (!bExist) {
3433 if (m_bHaveAcroForm) { 3410 if (m_bHaveAcroForm) {
3434 m_docStatus = PDF_DATAAVAIL_ACROFORM; 3411 m_docStatus = PDF_DATAAVAIL_ACROFORM;
3435 } else { 3412 } else {
3436 m_docStatus = PDF_DATAAVAIL_PAGETREE; 3413 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3437 } 3414 }
3438 return TRUE; 3415 return TRUE;
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
3708 FX_FILESIZE offset = m_dwLastXRefOffset; 3685 FX_FILESIZE offset = m_dwLastXRefOffset;
3709 if (dwSize < 512 && dwFileLen > 512) { 3686 if (dwSize < 512 && dwFileLen > 512) {
3710 dwSize = 512; 3687 dwSize = 512;
3711 offset = dwFileLen - 512; 3688 offset = dwFileLen - 512;
3712 } 3689 }
3713 pHints->AddSegment(offset, dwSize); 3690 pHints->AddSegment(offset, dwSize);
3714 } 3691 }
3715 } else { 3692 } else {
3716 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; 3693 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
3717 } 3694 }
3718 if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { 3695 if (bNeedDownLoad || m_docStatus != PDF_DATAAVAIL_FIRSTPAGE_PREPARE) {
3696 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
3697 return FALSE;
3698 }
3699 m_docStatus =
3700 m_bSupportHintTable ? PDF_DATAAVAIL_HINTTABLE : PDF_DATAAVAIL_DONE;
3701 return TRUE;
3702 }
3703 FX_BOOL CPDF_DataAvail::IsDataAvail(FX_FILESIZE offset,
3704 FX_DWORD size,
3705 IFX_DownloadHints* pHints) {
3706 if (!pHints || offset > m_dwFileLen) {
3707 return TRUE;
3708 }
3709 FX_SAFE_DWORD safeSize = pdfium::base::checked_cast<FX_DWORD>(offset);
3710 safeSize += size;
3711 safeSize += 512;
3712 if (!safeSize.IsValid()) {
3713 return TRUE;
3714 }
3715 if (safeSize.ValueOrDie() > m_dwFileLen) {
3716 size = m_dwFileLen - offset;
3717 } else {
3718 size += 512;
3719 }
3720 if (!m_pFileAvail->IsDataAvail(offset, size)) {
3721 pHints->AddSegment(offset, size);
3722 return FALSE;
3723 }
3724 return TRUE;
3725 }
3726 FX_BOOL CPDF_DataAvail::CheckHintTables(IFX_DownloadHints* pHints) {
3727 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
3728 if (!pDict || !pHints) {
3729 return TRUE;
3730 }
3731 if (!pDict->KeyExist(FX_BSTRC("H")) || !pDict->KeyExist(FX_BSTRC("O")) ||
3732 !pDict->KeyExist(FX_BSTRC("N"))) {
3719 m_docStatus = PDF_DATAAVAIL_DONE; 3733 m_docStatus = PDF_DATAAVAIL_DONE;
3720 return TRUE; 3734 return TRUE;
3721 } 3735 }
3722 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; 3736 int nPageCount = pDict->GetElementValue(FX_BSTRC("N"))->GetInteger();
3723 return FALSE; 3737 if (nPageCount <= 1) {
3724 } 3738 m_docStatus = PDF_DATAAVAIL_DONE;
3725 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, 3739 return TRUE;
3726 FX_DWORD objnum) { 3740 }
3741 CPDF_Array* pHintStreamRange = pDict->GetArray(FX_BSTRC("H"));
3742 FX_FILESIZE szHSStart, szHSLength;
Tom Sepez 2015/09/22 00:05:39 nit: one per line, combine declaration and initial
jun_fang 2015/09/22 12:42:32 Acknowledged.
3743 szHSStart = pHintStreamRange->GetElementValue(0)
3744 ? pHintStreamRange->GetElementValue(0)->GetInteger()
3745 : 0;
3746 szHSLength = pHintStreamRange->GetElementValue(1)
3747 ? pHintStreamRange->GetElementValue(1)->GetInteger()
3748 : 0;
3749 if (szHSStart < 0 || szHSLength <= 0) {
3750 m_docStatus = PDF_DATAAVAIL_DONE;
3751 return TRUE;
3752 }
3753 if (!IsDataAvail(szHSStart, szHSLength, pHints)) {
3754 return FALSE;
3755 }
3756 m_syntaxParser.InitParser(m_pFileRead, m_dwHeaderOffset);
3757 CPDF_HintTables* pHintTables = new CPDF_HintTables(this, pDict);
Tom Sepez 2015/09/22 00:05:39 nit: unique_ptr<> might help here, as well.
jun_fang 2015/09/22 12:42:32 If we define pHintTables and m_pHintTables like be
Tom Sepez 2015/09/22 15:16:43 See nonstd::move() (recently added) (a websearch o
3758 CPDF_Stream* pHintStream = (CPDF_Stream*)ParseIndirectObjectAt(szHSStart, 0);
3759 if (!pHintStream || pHintStream->GetType() != PDFOBJ_STREAM) {
3760 delete pHintTables;
3761 pHintTables = NULL;
3762 }
3763 if (pHintTables && !pHintTables->LoadHintStream(pHintStream)) {
3764 delete pHintTables;
3765 pHintTables = NULL;
3766 }
3767 m_pHintTables = pHintTables;
3768 m_docStatus = PDF_DATAAVAIL_DONE;
3769 return TRUE;
3770 }
3771 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(
3772 FX_FILESIZE pos,
3773 FX_DWORD objnum,
3774 CPDF_IndirectObjects* pObjList) {
3727 FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); 3775 FX_FILESIZE SavedPos = m_syntaxParser.SavePos();
3728 m_syntaxParser.RestorePos(pos); 3776 m_syntaxParser.RestorePos(pos);
3729 FX_BOOL bIsNumber; 3777 FX_BOOL bIsNumber;
3730 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); 3778 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber);
3731 if (!bIsNumber) { 3779 if (!bIsNumber) {
3732 return NULL; 3780 return NULL;
3733 } 3781 }
3734 FX_DWORD parser_objnum = FXSYS_atoi(word); 3782 FX_DWORD parser_objnum = FXSYS_atoi(word);
3735 if (objnum && parser_objnum != objnum) { 3783 if (objnum && parser_objnum != objnum) {
3736 return NULL; 3784 return NULL;
3737 } 3785 }
3738 word = m_syntaxParser.GetNextWord(bIsNumber); 3786 word = m_syntaxParser.GetNextWord(bIsNumber);
3739 if (!bIsNumber) { 3787 if (!bIsNumber) {
3740 return NULL; 3788 return NULL;
3741 } 3789 }
3742 FX_DWORD gennum = FXSYS_atoi(word); 3790 FX_DWORD gennum = FXSYS_atoi(word);
3743 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { 3791 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) {
3744 m_syntaxParser.RestorePos(SavedPos); 3792 m_syntaxParser.RestorePos(SavedPos);
3745 return NULL; 3793 return NULL;
3746 } 3794 }
3747 CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0); 3795 CPDF_Object* pObj =
3796 m_syntaxParser.GetObject(pObjList, parser_objnum, gennum, 0);
3748 m_syntaxParser.RestorePos(SavedPos); 3797 m_syntaxParser.RestorePos(SavedPos);
3749 return pObj; 3798 return pObj;
3750 } 3799 }
3751 int32_t CPDF_DataAvail::IsLinearizedPDF() { 3800 int32_t CPDF_DataAvail::IsLinearizedPDF() {
3752 FX_DWORD req_size = 1024; 3801 FX_DWORD req_size = 1024;
3753 if (!m_pFileAvail->IsDataAvail(0, req_size)) { 3802 if (!m_pFileAvail->IsDataAvail(0, req_size)) {
3754 return PDF_UNKNOW_LINEARIZED; 3803 return PDF_UNKNOW_LINEARIZED;
3755 } 3804 }
3756 if (!m_pFileRead) { 3805 if (!m_pFileRead) {
3757 return PDF_NOT_LINEARIZED; 3806 return PDF_NOT_LINEARIZED;
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
4495 return TRUE; 4544 return TRUE;
4496 } 4545 }
4497 if (m_bLinearized) { 4546 if (m_bLinearized) {
4498 if ((FX_DWORD)iPage == m_dwFirstPageNo) { 4547 if ((FX_DWORD)iPage == m_dwFirstPageNo) {
4499 m_pagesLoadState.insert(iPage); 4548 m_pagesLoadState.insert(iPage);
4500 return TRUE; 4549 return TRUE;
4501 } 4550 }
4502 if (!CheckLinearizedData(pHints)) { 4551 if (!CheckLinearizedData(pHints)) {
4503 return FALSE; 4552 return FALSE;
4504 } 4553 }
4505 if (m_bMainXRefLoadedOK) { 4554 if (m_pHintTables) {
4506 if (m_bTotalLoadPageTree) { 4555 if (!m_pHintTables->CheckPage(iPage, pHints)) {
Tom Sepez 2015/09/22 00:05:38 nit: just return m_pHintTabls->CheckPage(...);
jun_fang 2015/09/22 12:42:32 Acknowledged.
4507 if (!LoadPages(pHints)) { 4556 return FALSE;
4557 }
4558 return TRUE;
4559 } else {
Tom Sepez 2015/09/22 00:05:39 nit: else after return not needed.
jun_fang 2015/09/22 12:42:32 Acknowledged.
4560 if (m_bMainXRefLoadedOK) {
4561 if (m_bTotalLoadPageTree) {
4562 if (!LoadPages(pHints)) {
4563 return FALSE;
4564 }
4565 } else {
4566 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) {
4567 return FALSE;
4568 }
4569 }
4570 } else {
4571 if (!LoadAllFile(pHints)) {
4508 return FALSE; 4572 return FALSE;
4509 } 4573 }
4510 } else { 4574 ((CPDF_Parser*)m_pDocument->GetParser())->RebuildCrossRef();
4511 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { 4575 ResetFirstCheck(iPage);
4512 return FALSE; 4576 return TRUE;
4513 } 4577 }
4514 }
4515 } else {
4516 if (!LoadAllFile(pHints)) {
4517 return FALSE;
4518 }
4519 ((CPDF_Parser*)m_pDocument->GetParser())->RebuildCrossRef();
4520 ResetFirstCheck(iPage);
4521 return TRUE;
4522 } 4578 }
4523 } else { 4579 } else {
4524 if (!m_bTotalLoadPageTree) { 4580 if (!m_bTotalLoadPageTree) {
4525 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { 4581 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) {
4526 return FALSE; 4582 return FALSE;
4527 } 4583 }
4528 } 4584 }
4529 } 4585 }
4530 if (m_bHaveAcroForm && !m_bAcroFormLoad) { 4586 if (m_bHaveAcroForm && !m_bAcroFormLoad) {
4531 if (!CheckAcroFormSubObject(pHints)) { 4587 if (!CheckAcroFormSubObject(pHints)) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
4615 } 4671 }
4616 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, 4672 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos,
4617 FX_DWORD* pSize) { 4673 FX_DWORD* pSize) {
4618 if (pPos) { 4674 if (pPos) {
4619 *pPos = m_dwLastXRefOffset; 4675 *pPos = m_dwLastXRefOffset;
4620 } 4676 }
4621 if (pSize) { 4677 if (pSize) {
4622 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); 4678 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset);
4623 } 4679 }
4624 } 4680 }
4681 int CPDF_DataAvail::GetPageCount() const {
4682 if (!m_pDocument && !m_pLinearized) {
4683 return 0;
4684 }
4685 if (m_pLinearized) {
4686 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
4687 CPDF_Object* pObj = pDict ? pDict->GetElementValue(FX_BSTRC("N")) : nullptr;
4688 return pObj ? pObj->GetInteger() : 0;
4689 }
4690 return m_pDocument->GetPageCount();
4691 }
4692 CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) {
4693 if (!m_pDocument || index < 0 || index >= this->GetPageCount()) {
4694 return nullptr;
4695 }
4696 if (m_pLinearized) {
4697 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
4698 CPDF_Object* pObj = pDict ? pDict->GetElementValue(FX_BSTRC("P")) : nullptr;
4699 int pageNum = pObj ? pObj->GetInteger() : 0;
4700 if (m_pHintTables && index != pageNum) {
4701 FX_FILESIZE szPageStartPos = 0;
4702 FX_FILESIZE szPageLength = 0;
4703 FX_DWORD dwObjNum = 0;
4704 FX_BOOL bPagePosGot = m_pHintTables->GetPagePos(index, szPageStartPos,
4705 szPageLength, dwObjNum);
4706 if (!bPagePosGot) {
4707 return nullptr;
4708 }
4709 m_syntaxParser.InitParser(m_pFileRead, (FX_DWORD)szPageStartPos);
4710 CPDF_Object* pPageDict = ParseIndirectObjectAt(0, dwObjNum, m_pDocument);
4711 if (!pPageDict) {
4712 return nullptr;
4713 }
4714 m_pDocument->InsertIndirectObject(dwObjNum, pPageDict);
4715 return pPageDict->GetDict();
4716 }
4717 }
4718 return m_pDocument->GetPage(index);
4719 }
4625 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) { 4720 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) {
4626 if (!m_pDocument) { 4721 if (!m_pDocument) {
4627 return PDFFORM_AVAIL; 4722 return PDFFORM_AVAIL;
4628 } 4723 }
4629 if (!m_bLinearizedFormParamLoad) { 4724 if (!m_bLinearizedFormParamLoad) {
4630 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); 4725 CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
4631 if (!pRoot) { 4726 if (!pRoot) {
4632 return PDFFORM_AVAIL; 4727 return PDFFORM_AVAIL;
4633 } 4728 }
4634 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); 4729 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm"));
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4682 return FALSE; 4777 return FALSE;
4683 } 4778 }
4684 CPDF_PageNode::~CPDF_PageNode() { 4779 CPDF_PageNode::~CPDF_PageNode() {
4685 int32_t iSize = m_childNode.GetSize(); 4780 int32_t iSize = m_childNode.GetSize();
4686 for (int32_t i = 0; i < iSize; ++i) { 4781 for (int32_t i = 0; i < iSize; ++i) {
4687 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; 4782 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i];
4688 delete pNode; 4783 delete pNode;
4689 } 4784 }
4690 m_childNode.RemoveAll(); 4785 m_childNode.RemoveAll();
4691 } 4786 }
4787 CPDF_HintTables::~CPDF_HintTables() {
4788 m_nFirstPageSharedObjs = 0;
4789 m_szFirstPageObjOffset = 0;
4790 m_dwDeltaNObjsArray.RemoveAll();
4791 m_dwNSharedObjsArray.RemoveAll();
4792 m_dwSharedObjNumArray.RemoveAll();
4793 m_dwIdentifierArray.RemoveAll();
4794 m_szPageOffsetArray.RemoveAll();
4795 m_szSharedObjOffsetArray.RemoveAll();
4796 }
4797 FX_DWORD CPDF_HintTables::GetItemLength(int index, CFX_FileSizeArray& szArray) {
Tom Sepez 2015/09/22 00:05:38 nit: const CFX_FileSizeArray&
jun_fang 2015/09/22 12:42:32 Acknowledged.
4798 if (index < 0 || index > szArray.GetSize() - 2) {
4799 return 0;
4800 }
4801 return (szArray[index + 1] - szArray[index]);
Tom Sepez 2015/09/22 00:05:39 nit: unnecessary ()
jun_fang 2015/09/22 12:42:32 Acknowledged.
4802 }
4803 FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream& h) {
4804 if (!m_pLinearizedDict) {
4805 return FALSE;
4806 }
4807 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H"));
4808 CPDF_Object* pStreamOffset = pRange ? pRange->GetElementValue(0) : nullptr;
4809 CPDF_Object* pStreamLen = pRange ? pRange->GetElementValue(1) : nullptr;
Tom Sepez 2015/09/22 00:05:39 nit: prefer early return here rather than duplicat
jun_fang 2015/09/22 12:42:32 Acknowledged.
4810 int nStreamOffset = pStreamOffset ? pStreamOffset->GetInteger() : -1;
4811 int nStreanLen = pStreamLen ? pStreamLen->GetInteger() : 0;
Tom Sepez 2015/09/22 00:05:39 nit: typo: stream vs. strean
jun_fang 2015/09/22 12:42:32 Acknowledged.
4812 if (nStreamOffset < 0 || nStreanLen < 1) {
4813 return FALSE;
4814 }
4815 // Item 1: The least number of objects in a page.
4816 FX_DWORD dwObjLeastNum = h.GetBits(32);
4817 // Item 2: The location of the first page¡¯s page object.
Tom Sepez 2015/09/22 00:05:38 nit: typo.
jun_fang 2015/09/22 12:42:32 Acknowledged.
4818 FX_DWORD dwFirstObjLoc = h.GetBits(32);
4819 if (dwFirstObjLoc > nStreamOffset) {
4820 m_szFirstPageObjOffset = dwFirstObjLoc + nStreanLen;
Tom Sepez 2015/09/22 00:05:38 how do we know this doesn't overflow?
jun_fang 2015/09/22 12:42:32 Acknowledged.
4821 } else {
4822 m_szFirstPageObjOffset = dwFirstObjLoc;
4823 }
4824 // Item 3: The number of bits needed to represent the difference
4825 // between the greatest and least number of objects in a page.
4826 FX_DWORD dwDeltaObjectsBits = h.GetBits(16);
4827 // Item 4: The least length of a page in bytes.
4828 FX_DWORD dwPageLeastLen = h.GetBits(32);
4829 // Item 5: The number of bits needed to represent the difference
4830 // between the greatest and least length of a page, in bytes.
4831 FX_DWORD dwDeltaPageLenBits = h.GetBits(16);
4832 // Skip Item 6, 7, 8, 9 total 96 bits.
4833 h.SkipBits(96);
4834 // Item 10: The number of bits needed to represent the greatest
4835 // number of shared object references.
4836 FX_DWORD dwSharedObjBits = h.GetBits(16);
4837 // Item 11: The number of bits needed to represent the numerically
4838 // greatest shared object identifier used by the pages.
4839 FX_DWORD dwSharedIdBits = h.GetBits(16);
4840 // Item 12: The number of bits needed to represent the numerator of
4841 // the fractional position for each shared object reference. For each
4842 // shared object referenced from a page, there is an indication of
4843 // where in the page¡¯s content stream the object is first referenced.
Tom Sepez 2015/09/22 00:05:39 nit: typo
jun_fang 2015/09/22 12:42:32 Acknowledged.
4844 FX_DWORD dwSharedNumeratorBits = h.GetBits(16);
4845 // Item 13: The denominator of the fractional position for each shared
4846 // object reference. It's useless.
4847 FX_DWORD dwSharedDenominator = h.GetBits(16);
Tom Sepez 2015/09/22 00:05:39 nit: just skipbits for item 13 like above.
jun_fang 2015/09/22 12:42:32 Acknowledged.
4848 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N"));
4849 int nPages = pPageNum ? pPageNum->GetInteger() : 0;
4850 if (nPages < 1) {
4851 return FALSE;
4852 }
4853 for (int i = 0; i < nPages; ++i) {
4854 m_dwDeltaNObjsArray.Add(h.GetBits(dwDeltaObjectsBits) + dwObjLeastNum);
Tom Sepez 2015/09/22 00:05:38 overflow on addition?
jun_fang 2015/09/22 12:42:32 Acknowledged.
4855 }
4856 h.ByteAlign();
4857 CFX_DWordArray dwPageLenArray;
4858 for (int i = 0; i < nPages; ++i) {
4859 dwPageLenArray.Add(h.GetBits(dwDeltaPageLenBits) + dwPageLeastLen);
4860 }
4861 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E"));
4862 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1;
4863 if (nOffsetE < 0) {
4864 return FALSE;
4865 }
4866 CPDF_Object* pFirstPageNum =
4867 m_pLinearizedDict->GetElementValue(FX_BSTRC("P"));
4868 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0;
4869 for (int i = 0; i < nPages; ++i) {
4870 if (i == nFirstPageNum) {
4871 m_szPageOffsetArray.Add(m_szFirstPageObjOffset);
4872 } else if (i == nFirstPageNum + 1) {
4873 if (i == 1) {
4874 m_szPageOffsetArray.Add(nOffsetE);
4875 } else {
4876 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 2] +
4877 dwPageLenArray[i - 2]);
4878 }
4879 } else {
4880 if (i == 0) {
4881 m_szPageOffsetArray.Add(nOffsetE);
4882 } else {
4883 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 1] +
4884 dwPageLenArray[i - 1]);
4885 }
4886 }
4887 }
4888 if (nPages > 0) {
4889 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] +
4890 dwPageLenArray[nPages - 1]);
4891 } else {
4892 m_szPageOffsetArray.Add(m_szFirstPageObjOffset);
Tom Sepez 2015/09/22 00:05:38 I don't think this can be reached since we returne
jun_fang 2015/09/22 12:42:32 Acknowledged.
4893 m_szPageOffsetArray.Add(nOffsetE);
4894 }
4895 h.ByteAlign();
4896 /** The number of shared objects. */
Tom Sepez 2015/09/22 00:05:39 nit: prefer c++ // style.
jun_fang 2015/09/22 12:42:32 Acknowledged.
4897 for (int i = 0; i < nPages; i++) {
4898 m_dwNSharedObjsArray.Add(h.GetBits(dwSharedObjBits));
4899 }
4900 h.ByteAlign();
4901 // array of identifier, sizes = nshared_objects
4902 for (int i = 0; i < nPages; i++) {
4903 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) {
4904 m_dwIdentifierArray.Add(h.GetBits(dwSharedIdBits));
4905 }
4906 }
4907 h.ByteAlign();
4908 for (int i = 0; i < nPages; i++) {
4909 h.SkipBits(m_dwNSharedObjsArray[i] * dwSharedNumeratorBits);
Tom Sepez 2015/09/22 00:05:38 again, overflow?
4910 }
4911 h.ByteAlign();
4912 h.SkipBits(dwDeltaPageLenBits * nPages);
Tom Sepez 2015/09/22 00:05:39 overflow?
jun_fang 2015/09/22 12:42:32 Acknowledged.
4913 h.ByteAlign();
4914 return TRUE;
4915 }
4916 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream& h) {
4917 if (!m_pLinearizedDict) {
4918 return FALSE;
4919 }
4920 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H"));
Tom Sepez 2015/09/22 00:05:39 nit: same as above. Let's make a helper function a
jun_fang 2015/09/22 12:42:32 Acknowledged.
4921 CPDF_Object* pStreamOffset = pRange ? pRange->GetElementValue(0) : nullptr;
4922 CPDF_Object* pStreamLen = pRange ? pRange->GetElementValue(1) : nullptr;
4923 int nStreamOffset = pStreamOffset ? pStreamOffset->GetInteger() : -1;
4924 int nStreanLen = pStreamLen ? pStreamLen->GetInteger() : 0;
Tom Sepez 2015/09/22 00:05:39 nit: typo: stream vs. strean
jun_fang 2015/09/22 12:42:32 Acknowledged.
4925 if (nStreamOffset < 0 || nStreanLen < 1) {
4926 return FALSE;
4927 }
4928 // Item 1: The object number of the first object in the shared objects
4929 // section.
4930 FX_DWORD dwFirstSharedObjNum = h.GetBits(32);
4931 // Item 2: The location of the first object in the shared objects section.
4932 FX_DWORD dwFirstSharedObjLoc = h.GetBits(32);
4933 if (dwFirstSharedObjLoc > nStreamOffset) {
4934 dwFirstSharedObjLoc += nStreanLen;
4935 }
4936 // Item 3: The number of shared object entries for the first page.
4937 m_nFirstPageSharedObjs = h.GetBits(32);
4938 // Item 4: The number of shared object entries for the shared objects
4939 // section, including the number of shared object entries for the first page.
4940 FX_DWORD dwSharedObjTotal = h.GetBits(32);
4941 // Item 5: The number of bits needed to represent the greatest number of
4942 // objects in a shared object group. Skipped.
4943 h.SkipBits(16);
4944 // Item 6: The least length of a shared object group in bytes.
4945 FX_DWORD dwGroupLeastLen = h.GetBits(32);
4946 // Item 7: The number of bits needed to represent the difference between the
4947 // greatest and least length of a shared object group, in bytes.
4948 FX_DWORD dwDeltaGroupLen = h.GetBits(16);
4949 CPDF_Object* pFirstPageObj =
4950 m_pLinearizedDict->GetElementValue(FX_BSTRC("O"));
4951 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1;
4952 if (nFirstPageObjNum < 0) {
4953 return FALSE;
4954 }
4955 FX_DWORD dwSharedObjLen = 0;
4956 FX_DWORD dwSharedObjsLen = 0;
4957 for (int i = 0; i < dwSharedObjTotal; ++i) {
4958 dwSharedObjLen = dwSharedObjsLen;
4959 dwSharedObjsLen = h.GetBits(dwDeltaGroupLen) + dwGroupLeastLen;
Tom Sepez 2015/09/22 00:05:39 nit: overflow.
4960 if (i < m_nFirstPageSharedObjs) {
4961 m_dwSharedObjNumArray.Add(nFirstPageObjNum + i);
4962 if (i == 0) {
4963 m_szSharedObjOffsetArray.Add(m_szFirstPageObjOffset);
4964 } else {
4965 m_szSharedObjOffsetArray.Add(m_szSharedObjOffsetArray[i - 1] +
4966 dwSharedObjLen);
4967 }
4968 } else {
4969 m_dwSharedObjNumArray.Add(dwSharedObjTotal + i - m_nFirstPageSharedObjs);
4970 if (i == m_nFirstPageSharedObjs) {
4971 m_szSharedObjOffsetArray.Add(dwSharedObjTotal);
4972 } else {
4973 m_szSharedObjOffsetArray.Add(m_szSharedObjOffsetArray[i - 1] +
4974 dwSharedObjLen);
4975 }
4976 }
4977 }
4978 if (dwSharedObjTotal > 0) {
4979 m_szSharedObjOffsetArray.Add(
4980 m_szSharedObjOffsetArray[dwSharedObjTotal - 1] + dwSharedObjsLen);
4981 }
4982 h.ByteAlign();
4983 h.SkipBits(dwSharedObjTotal);
4984 h.ByteAlign();
4985 return TRUE;
4986 }
4987 FX_BOOL CPDF_HintTables::GetPagePos(int index,
4988 FX_FILESIZE& szPageStartPos,
4989 FX_FILESIZE& szPageLength,
4990 FX_DWORD& dwObjNum) {
4991 if (!m_pLinearizedDict) {
4992 return FALSE;
4993 }
4994 szPageStartPos = m_szPageOffsetArray[index];
4995 szPageLength = GetItemLength(index, m_szPageOffsetArray);
4996 CPDF_Object* pFirstPageNum =
4997 m_pLinearizedDict->GetElementValue(FX_BSTRC("P"));
4998 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0;
4999 CPDF_Object* pFirstPageObjNum =
5000 m_pLinearizedDict->GetElementValue(FX_BSTRC("O"));
5001 if (!pFirstPageObjNum) {
5002 return FALSE;
5003 }
5004 int nFirstPageObjNum = pFirstPageObjNum->GetInteger();
5005 if (index == nFirstPageNum) {
5006 dwObjNum = nFirstPageObjNum;
5007 return TRUE;
5008 }
5009 // The object number of remaining pages starts from 1.
5010 dwObjNum = 1;
5011 for (int i = 0; i < index; ++i) {
5012 if (i == nFirstPageNum) {
5013 continue;
5014 }
5015 dwObjNum += m_dwDeltaNObjsArray[i];
5016 }
5017 return TRUE;
5018 }
5019 FX_BOOL CPDF_HintTables::CheckPage(int index, IFX_DownloadHints* pHints) {
5020 if (!m_pLinearizedDict) {
5021 return FALSE;
5022 }
5023 CPDF_Object* pFirstAvailPage =
5024 m_pLinearizedDict->GetElementValue(FX_BSTRC("P"));
5025 int nFirstAvailPage = pFirstAvailPage ? pFirstAvailPage->GetInteger() : 0;
5026 if (index == nFirstAvailPage) {
5027 return TRUE;
5028 }
5029 FX_DWORD dwLength = GetItemLength(index, m_szPageOffsetArray);
5030 if (!dwLength ||
5031 !m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength,
5032 pHints)) {
5033 return FALSE;
5034 }
5035 // Download data of shared objects in the page.
5036 FX_DWORD offset = 0;
5037 for (int i = 0; i < index; ++i) {
5038 offset += m_dwNSharedObjsArray[i];
5039 }
5040 CPDF_Object* pFirstPageObj =
5041 m_pLinearizedDict->GetElementValue(FX_BSTRC("O"));
5042 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1;
5043 if (nFirstPageObjNum < 0) {
5044 return FALSE;
5045 }
5046 FX_DWORD dwIndex = 0;
5047 FX_DWORD dwObjNum = 0;
5048 for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) {
5049 dwIndex = m_dwIdentifierArray[offset + j];
Tom Sepez 2015/09/22 00:05:38 how do we know that the bounds are trustworthy her
5050 dwObjNum = m_dwSharedObjNumArray[dwIndex];
5051 if (dwObjNum >= nFirstPageObjNum &&
5052 dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) {
5053 continue;
5054 }
5055 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray);
5056 if (!dwLength ||
5057 !m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength,
5058 pHints)) {
5059 return FALSE;
5060 }
5061 }
5062 return TRUE;
5063 }
5064 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) {
5065 if (!pHintStream || !m_pLinearizedDict) {
5066 return FALSE;
5067 }
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 }
5073 CPDF_StreamAcc acc;
5074 acc.LoadAllData(pHintStream);
5075 FX_DWORD size = acc.GetSize();
5076 // The header section of page offset hint table is 36 bytes.
5077 // The header section of shared object hint table is 24 bytes.
5078 // Hint table has at least 60 bytes.
5079 const FX_DWORD MIN_STREAM_LEN = 60;
5080 if (size < MIN_STREAM_LEN || size < pOffset->GetInteger() ||
5081 !pOffset->GetInteger()) {
5082 return FALSE;
5083 }
5084 const uint8_t* pData = acc.GetData();
Tom Sepez 2015/09/22 00:05:39 nit: don't ned a local here, just bs.Init(acc.GetD
jun_fang 2015/09/22 12:42:32 Acknowledged.
5085 CFX_BitStream bs;
5086 bs.Init(pData, size);
5087 if (!ReadPageHintTable(bs) || !ReadSharedObjHintTable(bs)) {
Tom Sepez 2015/09/22 00:05:39 nit: or just return ReadPageHintTable(bs) && r
jun_fang 2015/09/22 12:42:32 Acknowledged.
5088 return FALSE;
5089 }
5090 return TRUE;
5091 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698