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

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

Powered by Google App Engine
This is Rietveld 408576698