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

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: Change pdfium_test and add the third return value to indicate an error 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) {
3190 if (!pHints) {
jun_fang 2015/10/21 11:08:11 It's checked in APIs.
3191 return PDF_DATA_ERROR;
3192 }
3189 if (!m_dwFileLen && m_pFileRead) { 3193 if (!m_dwFileLen && m_pFileRead) {
3190 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); 3194 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
3191 if (!m_dwFileLen) { 3195 if (!m_dwFileLen) {
3192 return TRUE; 3196 return PDF_DATA_ERROR;
3193 } 3197 }
3194 } 3198 }
3195 while (!m_bDocAvail) { 3199 while (!m_bDocAvail) {
3196 if (!CheckDocStatus(pHints)) { 3200 if (!CheckDocStatus(pHints)) {
3197 return FALSE; 3201 return PDF_DATA_NOTAVAIL;
3198 } 3202 }
3199 } 3203 }
3200 return TRUE; 3204 return PDF_DATA_AVAIL;
3201 } 3205 }
3202 FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) { 3206 FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) {
3203 if (!m_objs_array.GetSize()) { 3207 if (!m_objs_array.GetSize()) {
3204 m_objs_array.RemoveAll(); 3208 m_objs_array.RemoveAll();
3205 m_objnum_array.RemoveAll(); 3209 m_objnum_array.RemoveAll();
3206 CFX_PtrArray obj_array; 3210 CFX_PtrArray obj_array;
3207 obj_array.Append(m_arrayAcroforms); 3211 obj_array.Append(m_arrayAcroforms);
3208 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); 3212 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
3209 if (bRet) { 3213 if (bRet) {
3210 m_objs_array.RemoveAll(); 3214 m_objs_array.RemoveAll();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3243 m_docStatus = PDF_DATAAVAIL_PAGETREE; 3247 m_docStatus = PDF_DATAAVAIL_PAGETREE;
3244 return TRUE; 3248 return TRUE;
3245 } 3249 }
3246 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { 3250 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) {
3247 switch (m_docStatus) { 3251 switch (m_docStatus) {
3248 case PDF_DATAAVAIL_HEADER: 3252 case PDF_DATAAVAIL_HEADER:
3249 return CheckHeader(pHints); 3253 return CheckHeader(pHints);
3250 case PDF_DATAAVAIL_FIRSTPAGE: 3254 case PDF_DATAAVAIL_FIRSTPAGE:
3251 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: 3255 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE:
3252 return CheckFirstPage(pHints); 3256 return CheckFirstPage(pHints);
3257 case PDF_DATAAVAIL_HINTTABLE:
3258 return CheckHintTables(pHints);
3253 case PDF_DATAAVAIL_END: 3259 case PDF_DATAAVAIL_END:
3254 return CheckEnd(pHints); 3260 return CheckEnd(pHints);
3255 case PDF_DATAAVAIL_CROSSREF: 3261 case PDF_DATAAVAIL_CROSSREF:
3256 return CheckCrossRef(pHints); 3262 return CheckCrossRef(pHints);
3257 case PDF_DATAAVAIL_CROSSREF_ITEM: 3263 case PDF_DATAAVAIL_CROSSREF_ITEM:
3258 return CheckCrossRefItem(pHints); 3264 return CheckCrossRefItem(pHints);
3259 case PDF_DATAAVAIL_CROSSREF_STREAM: 3265 case PDF_DATAAVAIL_CROSSREF_STREAM:
3260 return CheckAllCrossRefStream(pHints); 3266 return CheckAllCrossRefStream(pHints);
3261 case PDF_DATAAVAIL_TRAILER: 3267 case PDF_DATAAVAIL_TRAILER:
3262 return CheckTrailer(pHints); 3268 return CheckTrailer(pHints);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
3327 CompareFileSize); 3333 CompareFileSize);
3328 m_dwRootObjNum = m_parser.GetRootObjNum(); 3334 m_dwRootObjNum = m_parser.GetRootObjNum();
3329 m_dwInfoObjNum = m_parser.GetInfoObjNum(); 3335 m_dwInfoObjNum = m_parser.GetInfoObjNum();
3330 m_pCurrentParser = &m_parser; 3336 m_pCurrentParser = &m_parser;
3331 m_docStatus = PDF_DATAAVAIL_ROOT; 3337 m_docStatus = PDF_DATAAVAIL_ROOT;
3332 return TRUE; 3338 return TRUE;
3333 } 3339 }
3334 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, 3340 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum,
3335 IFX_DownloadHints* pHints, 3341 IFX_DownloadHints* pHints,
3336 FX_BOOL* pExistInFile) { 3342 FX_BOOL* pExistInFile) {
3337 CPDF_Object* pRet = NULL; 3343 CPDF_Object* pRet = nullptr;
3338 FX_DWORD original_size = 0; 3344 FX_DWORD size = 0;
3339 FX_FILESIZE offset = 0; 3345 FX_FILESIZE offset = 0;
3340 CPDF_Parser* pParser = NULL; 3346 CPDF_Parser* pParser = nullptr;
3341 3347 if (pExistInFile)
3342 if (pExistInFile) {
3343 *pExistInFile = TRUE; 3348 *pExistInFile = TRUE;
3344 }
3345 3349
3346 if (m_pDocument == NULL) { 3350 if (m_pDocument == NULL) {
3347 original_size = (FX_DWORD)m_parser.GetObjectSize(objnum); 3351 size = (FX_DWORD)m_parser.GetObjectSize(objnum);
3348 offset = m_parser.GetObjectOffset(objnum); 3352 offset = m_parser.GetObjectOffset(objnum);
3349 pParser = &m_parser; 3353 pParser = &m_parser;
3350 } else { 3354 } else {
3351 original_size = GetObjectSize(objnum, offset); 3355 size = GetObjectSize(objnum, offset);
3352 pParser = (CPDF_Parser*)(m_pDocument->GetParser()); 3356 pParser = (CPDF_Parser*)(m_pDocument->GetParser());
3353 } 3357 }
3354 3358 if (!IsDataAvail(offset, size, pHints)) {
3355 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; 3359 return nullptr;
3356 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) {
3357 if (pExistInFile)
3358 *pExistInFile = FALSE;
3359
3360 return NULL;
3361 } 3360 }
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) { 3361 if (pParser) {
3385 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); 3362 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL);
3386 } 3363 }
3387 3364
3388 if (!pRet && pExistInFile) { 3365 if (!pRet && pExistInFile) {
3389 *pExistInFile = FALSE; 3366 *pExistInFile = FALSE;
3390 } 3367 }
3391 3368
3392 return pRet; 3369 return pRet;
3393 } 3370 }
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
3674 FX_FILESIZE offset = m_dwLastXRefOffset; 3651 FX_FILESIZE offset = m_dwLastXRefOffset;
3675 if (dwSize < 512 && dwFileLen > 512) { 3652 if (dwSize < 512 && dwFileLen > 512) {
3676 dwSize = 512; 3653 dwSize = 512;
3677 offset = dwFileLen - 512; 3654 offset = dwFileLen - 512;
3678 } 3655 }
3679 pHints->AddSegment(offset, dwSize); 3656 pHints->AddSegment(offset, dwSize);
3680 } 3657 }
3681 } else { 3658 } else {
3682 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; 3659 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
3683 } 3660 }
3684 if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { 3661 if (bNeedDownLoad || m_docStatus != PDF_DATAAVAIL_FIRSTPAGE_PREPARE) {
3662 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
3663 return FALSE;
3664 }
3665 m_docStatus =
3666 m_bSupportHintTable ? PDF_DATAAVAIL_HINTTABLE : PDF_DATAAVAIL_DONE;
3667 return TRUE;
3668 }
3669 FX_BOOL CPDF_DataAvail::IsDataAvail(FX_FILESIZE offset,
3670 FX_DWORD size,
3671 IFX_DownloadHints* pHints) {
3672 if (!pHints || offset > m_dwFileLen)
3673 return TRUE;
3674 FX_SAFE_DWORD safeSize = pdfium::base::checked_cast<FX_DWORD>(offset);
3675 safeSize += size;
3676 safeSize += 512;
3677 if (!safeSize.IsValid() || safeSize.ValueOrDie() > m_dwFileLen)
3678 size = m_dwFileLen - offset;
3679 else
3680 size += 512;
3681 if (!m_pFileAvail->IsDataAvail(offset, size)) {
3682 pHints->AddSegment(offset, size);
3683 return FALSE;
3684 }
3685 return TRUE;
3686 }
3687 FX_BOOL CPDF_DataAvail::CheckHintTables(IFX_DownloadHints* pHints) {
3688 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
3689 if (!pDict || !pHints) {
3685 m_docStatus = PDF_DATAAVAIL_DONE; 3690 m_docStatus = PDF_DATAAVAIL_DONE;
3686 return TRUE; 3691 return TRUE;
3687 } 3692 }
3688 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; 3693 if (!pDict->KeyExist(FX_BSTRC("H")) || !pDict->KeyExist(FX_BSTRC("O")) ||
3689 return FALSE; 3694 !pDict->KeyExist(FX_BSTRC("N"))) {
3695 m_docStatus = PDF_DATAAVAIL_DONE;
3696 return TRUE;
3697 }
3698 int nPageCount = pDict->GetElementValue(FX_BSTRC("N"))->GetInteger();
3699 if (nPageCount <= 1) {
3700 m_docStatus = PDF_DATAAVAIL_DONE;
3701 return TRUE;
3702 }
3703 CPDF_Array* pHintStreamRange = pDict->GetArray(FX_BSTRC("H"));
3704 FX_FILESIZE szHSStart =
3705 pHintStreamRange->GetElementValue(0)
3706 ? pHintStreamRange->GetElementValue(0)->GetInteger()
3707 : 0;
3708 FX_FILESIZE szHSLength =
3709 pHintStreamRange->GetElementValue(1)
3710 ? pHintStreamRange->GetElementValue(1)->GetInteger()
3711 : 0;
3712 if (szHSStart < 0 || szHSLength <= 0) {
3713 m_docStatus = PDF_DATAAVAIL_DONE;
3714 return TRUE;
3715 }
3716 if (!IsDataAvail(szHSStart, szHSLength, pHints)) {
3717 return FALSE;
3718 }
3719 m_syntaxParser.InitParser(m_pFileRead, m_dwHeaderOffset);
3720 nonstd::unique_ptr<CPDF_HintTables> pHintTables(
3721 new CPDF_HintTables(this, pDict));
3722 CPDF_Stream* pHintStream = (CPDF_Stream*)ParseIndirectObjectAt(szHSStart, 0);
3723 FX_BOOL bLoaded = FALSE;
3724 if (pHintTables && pHintStream && pHintStream->GetType() == PDFOBJ_STREAM) {
3725 bLoaded = pHintTables->LoadHintStream(pHintStream);
3726 }
3727 if (!bLoaded) {
3728 m_pHintTables.reset(pHintTables.release());
3729 }
3730 m_docStatus = PDF_DATAAVAIL_DONE;
3731 return TRUE;
3690 } 3732 }
3691 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, 3733 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(
3692 FX_DWORD objnum) { 3734 FX_FILESIZE pos,
3735 FX_DWORD objnum,
3736 CPDF_IndirectObjects* pObjList) {
3693 FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); 3737 FX_FILESIZE SavedPos = m_syntaxParser.SavePos();
3694 m_syntaxParser.RestorePos(pos); 3738 m_syntaxParser.RestorePos(pos);
3695 FX_BOOL bIsNumber; 3739 FX_BOOL bIsNumber;
3696 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); 3740 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber);
3697 if (!bIsNumber) { 3741 if (!bIsNumber) {
3698 return NULL; 3742 return NULL;
3699 } 3743 }
3700 FX_DWORD parser_objnum = FXSYS_atoi(word); 3744 FX_DWORD parser_objnum = FXSYS_atoi(word);
3701 if (objnum && parser_objnum != objnum) { 3745 if (objnum && parser_objnum != objnum) {
3702 return NULL; 3746 return NULL;
3703 } 3747 }
3704 word = m_syntaxParser.GetNextWord(bIsNumber); 3748 word = m_syntaxParser.GetNextWord(bIsNumber);
3705 if (!bIsNumber) { 3749 if (!bIsNumber) {
3706 return NULL; 3750 return NULL;
3707 } 3751 }
3708 FX_DWORD gennum = FXSYS_atoi(word); 3752 FX_DWORD gennum = FXSYS_atoi(word);
3709 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { 3753 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) {
3710 m_syntaxParser.RestorePos(SavedPos); 3754 m_syntaxParser.RestorePos(SavedPos);
3711 return NULL; 3755 return NULL;
3712 } 3756 }
3713 CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0); 3757 CPDF_Object* pObj =
3758 m_syntaxParser.GetObject(pObjList, parser_objnum, gennum, 0);
3714 m_syntaxParser.RestorePos(SavedPos); 3759 m_syntaxParser.RestorePos(SavedPos);
3715 return pObj; 3760 return pObj;
3716 } 3761 }
3717 int32_t CPDF_DataAvail::IsLinearizedPDF() { 3762 int32_t CPDF_DataAvail::IsLinearizedPDF() {
3718 FX_DWORD req_size = 1024; 3763 FX_DWORD req_size = 1024;
3719 if (!m_pFileAvail->IsDataAvail(0, req_size)) { 3764 if (!m_pFileAvail->IsDataAvail(0, req_size)) {
3720 return PDF_UNKNOW_LINEARIZED; 3765 return PDF_LINEARIZATION_UNKNOWN;
3721 } 3766 }
3722 if (!m_pFileRead) { 3767 if (!m_pFileRead) {
3723 return PDF_NOT_LINEARIZED; 3768 return PDF_NOT_LINEARIZED;
3724 } 3769 }
3725 FX_FILESIZE dwSize = m_pFileRead->GetSize(); 3770 FX_FILESIZE dwSize = m_pFileRead->GetSize();
3726 if (dwSize < (FX_FILESIZE)req_size) { 3771 if (dwSize < (FX_FILESIZE)req_size) {
3727 return PDF_UNKNOW_LINEARIZED; 3772 return PDF_LINEARIZATION_UNKNOWN;
3728 } 3773 }
3729 uint8_t buffer[1024]; 3774 uint8_t buffer[1024];
3730 m_pFileRead->ReadBlock(buffer, 0, req_size); 3775 m_pFileRead->ReadBlock(buffer, 0, req_size);
3731 if (IsLinearizedFile(buffer, req_size)) { 3776 if (IsLinearizedFile(buffer, req_size)) {
3732 return PDF_IS_LINEARIZED; 3777 return PDF_LINEARIZED;
3733 } 3778 }
3734 return PDF_NOT_LINEARIZED; 3779 return PDF_NOT_LINEARIZED;
3735 } 3780 }
3736 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { 3781 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) {
3737 CFX_SmartPointer<IFX_FileStream> file( 3782 CFX_SmartPointer<IFX_FileStream> file(
3738 FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); 3783 FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE));
3739 int32_t offset = GetHeaderOffset(file.Get()); 3784 int32_t offset = GetHeaderOffset(file.Get());
3740 if (offset == -1) { 3785 if (offset == -1) {
3741 m_docStatus = PDF_DATAAVAIL_ERROR; 3786 m_docStatus = PDF_DATAAVAIL_ERROR;
3742 return FALSE; 3787 return FALSE;
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
4343 if (!CheckPageStatus(pHints)) { 4388 if (!CheckPageStatus(pHints)) {
4344 return FALSE; 4389 return FALSE;
4345 } 4390 }
4346 } 4391 }
4347 if (m_bPagesLoad) { 4392 if (m_bPagesLoad) {
4348 return TRUE; 4393 return TRUE;
4349 } 4394 }
4350 m_pDocument->LoadPages(); 4395 m_pDocument->LoadPages();
4351 return FALSE; 4396 return FALSE;
4352 } 4397 }
4353 FX_BOOL CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints) { 4398 int32_t CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints) {
4354 if (m_bLinearedDataOK) { 4399 if (m_bLinearedDataOK) {
4355 return TRUE; 4400 return PDF_DATA_AVAIL;
4356 } 4401 }
4357 4402
4358 if (!m_bMainXRefLoadTried) { 4403 if (!m_bMainXRefLoadTried) {
4359 FX_SAFE_DWORD data_size = m_dwFileLen; 4404 FX_SAFE_DWORD data_size = m_dwFileLen;
4360 data_size -= m_dwLastXRefOffset; 4405 data_size -= m_dwLastXRefOffset;
4361 if (!data_size.IsValid()) { 4406 if (!data_size.IsValid()) {
4362 return FALSE; 4407 return PDF_DATA_ERROR;
4363 } 4408 }
4364 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, 4409 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset,
4365 data_size.ValueOrDie())) { 4410 data_size.ValueOrDie())) {
4366 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie()); 4411 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie());
4367 return FALSE; 4412 return PDF_DATA_NOTAVAIL;
4368 } 4413 }
4369 FX_DWORD dwRet = 4414 FX_DWORD dwRet = (m_pDocument->GetParser())->LoadLinearizedMainXRefTable();
4370 ((CPDF_Parser*)m_pDocument->GetParser())->LoadLinearizedMainXRefTable();
4371 m_bMainXRefLoadTried = TRUE; 4415 m_bMainXRefLoadTried = TRUE;
4372 if (dwRet != PDFPARSE_ERROR_SUCCESS) { 4416 if (dwRet != PDFPARSE_ERROR_SUCCESS) {
4373 return FALSE; 4417 return PDF_DATA_ERROR;
4374 } 4418 }
4375 if (!PreparePageItem()) { 4419 if (!PreparePageItem()) {
4376 return FALSE; 4420 return PDF_DATA_NOTAVAIL;
4377 } 4421 }
4378 m_bMainXRefLoadedOK = TRUE; 4422 m_bMainXRefLoadedOK = TRUE;
4379 m_bLinearedDataOK = TRUE; 4423 m_bLinearedDataOK = TRUE;
4380 } 4424 }
4381 4425
4382 return m_bLinearedDataOK; 4426 return m_bLinearedDataOK ? PDF_DATA_AVAIL : PDF_DATA_NOTAVAIL;
4383 } 4427 }
4384 FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage, 4428 FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage,
4385 IFX_DownloadHints* pHints) { 4429 IFX_DownloadHints* pHints) {
4386 if (!m_objs_array.GetSize()) { 4430 if (!m_objs_array.GetSize()) {
4387 m_objs_array.RemoveAll(); 4431 m_objs_array.RemoveAll();
4388 m_objnum_array.RemoveAll(); 4432 m_objnum_array.RemoveAll();
4389 CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iPage); 4433 CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iPage);
4390 if (!pPageDict) { 4434 if (!pPageDict) {
4391 return TRUE; 4435 return TRUE;
4392 } 4436 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4438 if (!pParentDict) { 4482 if (!pParentDict) {
4439 return FALSE; 4483 return FALSE;
4440 } 4484 }
4441 CPDF_Object* pRet = pParentDict->GetElement("Resources"); 4485 CPDF_Object* pRet = pParentDict->GetElement("Resources");
4442 if (pRet) { 4486 if (pRet) {
4443 m_pPageResource = pRet; 4487 m_pPageResource = pRet;
4444 return TRUE; 4488 return TRUE;
4445 } 4489 }
4446 return HaveResourceAncestor(pParentDict); 4490 return HaveResourceAncestor(pParentDict);
4447 } 4491 }
4448 FX_BOOL CPDF_DataAvail::IsPageAvail(int32_t iPage, IFX_DownloadHints* pHints) { 4492 int32_t CPDF_DataAvail::IsPageAvail(int32_t iPage, IFX_DownloadHints* pHints) {
4449 if (!m_pDocument) { 4493 if (!m_pDocument || !pHints) {
jun_fang 2015/10/21 11:08:12 It's checked in API level.
4450 return FALSE; 4494 return PDF_DATA_ERROR;
4451 } 4495 }
4452 if (IsFirstCheck(iPage)) { 4496 if (IsFirstCheck(iPage)) {
4453 m_bCurPageDictLoadOK = FALSE; 4497 m_bCurPageDictLoadOK = FALSE;
4454 m_bPageLoadedOK = FALSE; 4498 m_bPageLoadedOK = FALSE;
4455 m_bAnnotsLoad = FALSE; 4499 m_bAnnotsLoad = FALSE;
4456 m_bNeedDownLoadResource = FALSE; 4500 m_bNeedDownLoadResource = FALSE;
4457 m_objs_array.RemoveAll(); 4501 m_objs_array.RemoveAll();
4458 m_objnum_array.RemoveAll(); 4502 m_objnum_array.RemoveAll();
4459 } 4503 }
4460 if (m_pagesLoadState.find(iPage) != m_pagesLoadState.end()) { 4504 if (m_pagesLoadState.find(iPage) != m_pagesLoadState.end()) {
4461 return TRUE; 4505 return PDF_DATA_AVAIL;
4462 } 4506 }
4463 if (m_bLinearized) { 4507 if (m_bLinearized) {
4464 if ((FX_DWORD)iPage == m_dwFirstPageNo) { 4508 if ((FX_DWORD)iPage == m_dwFirstPageNo) {
4465 m_pagesLoadState.insert(iPage); 4509 m_pagesLoadState.insert(iPage);
4466 return TRUE; 4510 return PDF_DATA_AVAIL;
4467 } 4511 }
4468 if (!CheckLinearizedData(pHints)) { 4512 int32_t nResult = CheckLinearizedData(pHints);
4469 return FALSE; 4513 if (nResult != PDF_DATA_AVAIL) {
4514 return nResult;
4515 }
4516 if (m_pHintTables) {
4517 nResult = m_pHintTables->CheckPage(iPage, pHints);
4518 if (nResult != PDF_DATA_AVAIL)
4519 return nResult;
4520 m_pagesLoadState.insert(iPage);
4521 return PDF_DATA_AVAIL;
4470 } 4522 }
4471 if (m_bMainXRefLoadedOK) { 4523 if (m_bMainXRefLoadedOK) {
4472 if (m_bTotalLoadPageTree) { 4524 if (m_bTotalLoadPageTree) {
4473 if (!LoadPages(pHints)) { 4525 if (!LoadPages(pHints)) {
4474 return FALSE; 4526 return PDF_DATA_NOTAVAIL;
4475 } 4527 }
4476 } else { 4528 } else {
4477 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { 4529 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) {
4478 return FALSE; 4530 return PDF_DATA_NOTAVAIL;
4479 } 4531 }
4480 } 4532 }
4481 } else { 4533 } else {
4482 if (!LoadAllFile(pHints)) { 4534 if (!LoadAllFile(pHints)) {
4483 return FALSE; 4535 return PDF_DATA_NOTAVAIL;
4484 } 4536 }
4485 ((CPDF_Parser*)m_pDocument->GetParser())->RebuildCrossRef(); 4537 ((CPDF_Parser*)m_pDocument->GetParser())->RebuildCrossRef();
4486 ResetFirstCheck(iPage); 4538 ResetFirstCheck(iPage);
4487 return TRUE; 4539 return PDF_DATA_AVAIL;
4488 } 4540 }
4489 } else { 4541 } else {
4490 if (!m_bTotalLoadPageTree) { 4542 if (!m_bTotalLoadPageTree) {
4491 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { 4543 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) {
4492 return FALSE; 4544 return PDF_DATA_NOTAVAIL;
4493 } 4545 }
4494 } 4546 }
4495 } 4547 }
4496 if (m_bHaveAcroForm && !m_bAcroFormLoad) { 4548 if (m_bHaveAcroForm && !m_bAcroFormLoad) {
4497 if (!CheckAcroFormSubObject(pHints)) { 4549 if (!CheckAcroFormSubObject(pHints)) {
4498 return FALSE; 4550 return PDF_DATA_NOTAVAIL;
4499 } 4551 }
4500 m_bAcroFormLoad = TRUE; 4552 m_bAcroFormLoad = TRUE;
4501 } 4553 }
4502 if (!m_bPageLoadedOK) { 4554 if (!m_bPageLoadedOK) {
4503 if (!m_objs_array.GetSize()) { 4555 if (!m_objs_array.GetSize()) {
4504 m_objs_array.RemoveAll(); 4556 m_objs_array.RemoveAll();
4505 m_objnum_array.RemoveAll(); 4557 m_objnum_array.RemoveAll();
4506 m_pPageDict = m_pDocument->GetPage(iPage); 4558 m_pPageDict = m_pDocument->GetPage(iPage);
4507 if (!m_pPageDict) { 4559 if (!m_pPageDict) {
4508 ResetFirstCheck(iPage); 4560 ResetFirstCheck(iPage);
4509 return TRUE; 4561 return PDF_DATA_AVAIL;
4510 } 4562 }
4511 CFX_PtrArray obj_array; 4563 CFX_PtrArray obj_array;
4512 obj_array.Add(m_pPageDict); 4564 obj_array.Add(m_pPageDict);
4513 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); 4565 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);
4514 if (bRet) { 4566 if (bRet) {
4515 m_objs_array.RemoveAll(); 4567 m_objs_array.RemoveAll();
4516 m_bPageLoadedOK = TRUE; 4568 m_bPageLoadedOK = TRUE;
4517 } else { 4569 } else {
4518 return bRet; 4570 return bRet;
4519 } 4571 }
4520 } else { 4572 } else {
4521 CFX_PtrArray new_objs_array; 4573 CFX_PtrArray new_objs_array;
4522 FX_BOOL bRet = 4574 FX_BOOL bRet =
4523 IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); 4575 IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
4524 m_objs_array.RemoveAll(); 4576 m_objs_array.RemoveAll();
4525 if (bRet) { 4577 if (bRet) {
4526 m_bPageLoadedOK = TRUE; 4578 m_bPageLoadedOK = TRUE;
4527 } else { 4579 } else {
4528 m_objs_array.Append(new_objs_array); 4580 m_objs_array.Append(new_objs_array);
4529 return bRet; 4581 return PDF_DATA_NOTAVAIL;
4530 } 4582 }
4531 } 4583 }
4532 } 4584 }
4533 if (m_bPageLoadedOK) { 4585 if (m_bPageLoadedOK) {
4534 if (!m_bAnnotsLoad) { 4586 if (!m_bAnnotsLoad) {
4535 if (!CheckPageAnnots(iPage, pHints)) { 4587 if (!CheckPageAnnots(iPage, pHints)) {
4536 return FALSE; 4588 return PDF_DATA_NOTAVAIL;
4537 } 4589 }
4538 m_bAnnotsLoad = TRUE; 4590 m_bAnnotsLoad = TRUE;
4539 } 4591 }
4540 } 4592 }
4541 if (m_pPageDict && !m_bNeedDownLoadResource) { 4593 if (m_pPageDict && !m_bNeedDownLoadResource) {
4542 m_pPageResource = m_pPageDict->GetElement("Resources"); 4594 m_pPageResource = m_pPageDict->GetElement("Resources");
4543 if (!m_pPageResource) { 4595 if (!m_pPageResource) {
4544 m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict); 4596 m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict);
4545 } else { 4597 } else {
4546 m_bNeedDownLoadResource = TRUE; 4598 m_bNeedDownLoadResource = TRUE;
4547 } 4599 }
4548 } 4600 }
4549 if (m_bNeedDownLoadResource) { 4601 if (m_bNeedDownLoadResource) {
4550 FX_BOOL bRet = CheckResources(pHints); 4602 FX_BOOL bRet = CheckResources(pHints);
4551 if (!bRet) { 4603 if (!bRet) {
4552 return FALSE; 4604 return PDF_DATA_NOTAVAIL;
4553 } 4605 }
4554 m_bNeedDownLoadResource = FALSE; 4606 m_bNeedDownLoadResource = FALSE;
4555 } 4607 }
4556 m_bPageLoadedOK = FALSE; 4608 m_bPageLoadedOK = FALSE;
4557 m_bAnnotsLoad = FALSE; 4609 m_bAnnotsLoad = FALSE;
4558 m_bCurPageDictLoadOK = FALSE; 4610 m_bCurPageDictLoadOK = FALSE;
4559 ResetFirstCheck(iPage); 4611 ResetFirstCheck(iPage);
4560 m_pagesLoadState.insert(iPage); 4612 m_pagesLoadState.insert(iPage);
4561 return TRUE; 4613 return PDF_DATA_AVAIL;
4562 } 4614 }
4563 FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) { 4615 FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) {
4564 if (!m_objs_array.GetSize()) { 4616 if (!m_objs_array.GetSize()) {
4565 m_objs_array.RemoveAll(); 4617 m_objs_array.RemoveAll();
4566 CFX_PtrArray obj_array; 4618 CFX_PtrArray obj_array;
4567 obj_array.Add(m_pPageResource); 4619 obj_array.Add(m_pPageResource);
4568 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); 4620 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);
4569 if (bRet) { 4621 if (bRet) {
4570 m_objs_array.RemoveAll(); 4622 m_objs_array.RemoveAll();
4571 } 4623 }
4572 return bRet; 4624 return bRet;
4573 } 4625 }
4574 CFX_PtrArray new_objs_array; 4626 CFX_PtrArray new_objs_array;
4575 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); 4627 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
4576 m_objs_array.RemoveAll(); 4628 m_objs_array.RemoveAll();
4577 if (!bRet) { 4629 if (!bRet) {
4578 m_objs_array.Append(new_objs_array); 4630 m_objs_array.Append(new_objs_array);
4579 } 4631 }
4580 return bRet; 4632 return bRet;
4581 } 4633 }
4582 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, 4634 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos,
4583 FX_DWORD* pSize) { 4635 FX_DWORD* pSize) {
4584 if (pPos) { 4636 if (pPos) {
4585 *pPos = m_dwLastXRefOffset; 4637 *pPos = m_dwLastXRefOffset;
4586 } 4638 }
4587 if (pSize) { 4639 if (pSize) {
4588 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); 4640 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset);
4589 } 4641 }
4590 } 4642 }
4643 int CPDF_DataAvail::GetPageCount() const {
4644 if (m_pLinearized) {
4645 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
4646 CPDF_Object* pObj = pDict ? pDict->GetElementValue(FX_BSTRC("N")) : nullptr;
4647 return pObj ? pObj->GetInteger() : 0;
4648 }
4649 return m_pDocument ? m_pDocument->GetPageCount() : 0;
4650 }
4651 CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) {
4652 if (!m_pDocument || index < 0 || index >= this->GetPageCount()) {
4653 return nullptr;
4654 }
4655 if (m_pLinearized) {
4656 CPDF_Dictionary* pDict = m_pLinearized->GetDict();
4657 CPDF_Object* pObj = pDict ? pDict->GetElementValue(FX_BSTRC("P")) : nullptr;
4658 int pageNum = pObj ? pObj->GetInteger() : 0;
4659 if (m_pHintTables && index != pageNum) {
4660 FX_FILESIZE szPageStartPos = 0;
4661 FX_FILESIZE szPageLength = 0;
4662 FX_DWORD dwObjNum = 0;
4663 FX_BOOL bPagePosGot = m_pHintTables->GetPagePos(index, szPageStartPos,
4664 szPageLength, dwObjNum);
4665 if (!bPagePosGot) {
4666 return nullptr;
4667 }
4668 m_syntaxParser.InitParser(m_pFileRead, (FX_DWORD)szPageStartPos);
4669 CPDF_Object* pPageDict = ParseIndirectObjectAt(0, dwObjNum, m_pDocument);
4670 if (!pPageDict) {
4671 return nullptr;
4672 }
4673 m_pDocument->InsertIndirectObject(dwObjNum, pPageDict);
4674 return pPageDict->GetDict();
4675 }
4676 }
4677 return m_pDocument->GetPage(index);
4678 }
4591 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) { 4679 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) {
4592 if (!m_pDocument) { 4680 if (!m_pDocument) {
4593 return PDFFORM_AVAIL; 4681 return PDF_FORM_AVAIL;
4594 } 4682 }
4595 if (!m_bLinearizedFormParamLoad) { 4683 if (!m_bLinearizedFormParamLoad) {
4596 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); 4684 CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
4597 if (!pRoot) { 4685 if (!pRoot) {
4598 return PDFFORM_AVAIL; 4686 return PDF_FORM_AVAIL;
4599 } 4687 }
4600 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); 4688 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm"));
4601 if (!pAcroForm) { 4689 if (!pAcroForm) {
4602 return PDFFORM_NOTEXIST; 4690 return PDF_FORM_NOTEXIST;
4603 } 4691 }
4604 if (!CheckLinearizedData(pHints)) { 4692 if (!CheckLinearizedData(pHints)) {
4605 return PDFFORM_NOTAVAIL; 4693 return PDF_FORM_NOTAVAIL;
4606 } 4694 }
4607 if (!m_objs_array.GetSize()) { 4695 if (!m_objs_array.GetSize()) {
4608 m_objs_array.Add(pAcroForm->GetDict()); 4696 m_objs_array.Add(pAcroForm->GetDict());
4609 } 4697 }
4610 m_bLinearizedFormParamLoad = TRUE; 4698 m_bLinearizedFormParamLoad = TRUE;
4611 } 4699 }
4612 CFX_PtrArray new_objs_array; 4700 CFX_PtrArray new_objs_array;
4613 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); 4701 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
4614 m_objs_array.RemoveAll(); 4702 m_objs_array.RemoveAll();
4615 if (!bRet) { 4703 if (!bRet) {
4616 m_objs_array.Append(new_objs_array); 4704 m_objs_array.Append(new_objs_array);
4617 return PDFFORM_NOTAVAIL; 4705 return PDF_FORM_NOTAVAIL;
4618 } 4706 }
4619 return PDFFORM_AVAIL; 4707 return PDF_FORM_AVAIL;
4620 } 4708 }
4621 void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) { 4709 void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) {
4622 int32_t iNext = 0; 4710 int32_t iNext = 0;
4623 if (BinarySearch(dwObjNum, iNext)) { 4711 if (BinarySearch(dwObjNum, iNext)) {
4624 return; 4712 return;
4625 } 4713 }
4626 m_number_array.InsertAt(iNext, dwObjNum); 4714 m_number_array.InsertAt(iNext, dwObjNum);
4627 } 4715 }
4628 FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) { 4716 FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) {
4629 int32_t iNext = 0; 4717 int32_t iNext = 0;
(...skipping 18 matching lines...) Expand all
4648 return FALSE; 4736 return FALSE;
4649 } 4737 }
4650 CPDF_PageNode::~CPDF_PageNode() { 4738 CPDF_PageNode::~CPDF_PageNode() {
4651 int32_t iSize = m_childNode.GetSize(); 4739 int32_t iSize = m_childNode.GetSize();
4652 for (int32_t i = 0; i < iSize; ++i) { 4740 for (int32_t i = 0; i < iSize; ++i) {
4653 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; 4741 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i];
4654 delete pNode; 4742 delete pNode;
4655 } 4743 }
4656 m_childNode.RemoveAll(); 4744 m_childNode.RemoveAll();
4657 } 4745 }
4746 CPDF_HintTables::~CPDF_HintTables() {
4747 m_dwDeltaNObjsArray.RemoveAll();
4748 m_dwNSharedObjsArray.RemoveAll();
4749 m_dwSharedObjNumArray.RemoveAll();
4750 m_dwIdentifierArray.RemoveAll();
4751 m_szPageOffsetArray.RemoveAll();
4752 m_szSharedObjOffsetArray.RemoveAll();
4753 }
4754 FX_DWORD CPDF_HintTables::GetItemLength(int index,
4755 const CFX_FileSizeArray& szArray) {
4756 if (index < 0 || szArray.GetSize() < 2 || index > szArray.GetSize() - 2 ||
4757 szArray[index] > szArray[index + 1])
4758 return 0;
4759 return szArray[index + 1] - szArray[index];
4760 }
4761 FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
4762 if (!hStream)
4763 return FALSE;
4764 int nStreamOffset = ReadPrimaryHintStreamOffset();
4765 int nStreamLen = ReadPrimaryHintStreamLength();
4766 if (nStreamOffset < 0 || nStreamLen < 1)
4767 return FALSE;
4768 // Item 1: The least number of objects in a page.
4769 FX_DWORD dwObjLeastNum = hStream->GetBits(32);
4770 // Item 2: The location of the first page's page object.
4771 FX_DWORD dwFirstObjLoc = hStream->GetBits(32);
4772 if (dwFirstObjLoc > nStreamOffset) {
4773 FX_SAFE_DWORD safeLoc = pdfium::base::checked_cast<FX_DWORD>(nStreamLen);
4774 safeLoc += dwFirstObjLoc;
4775 if (!safeLoc.IsValid())
4776 return FALSE;
4777 m_szFirstPageObjOffset =
4778 pdfium::base::checked_cast<FX_FILESIZE>(safeLoc.ValueOrDie());
4779 } else {
4780 m_szFirstPageObjOffset =
4781 pdfium::base::checked_cast<FX_FILESIZE>(dwFirstObjLoc);
4782 }
4783 // Item 3: The number of bits needed to represent the difference
4784 // between the greatest and least number of objects in a page.
4785 FX_DWORD dwDeltaObjectsBits = hStream->GetBits(16);
4786 // Item 4: The least length of a page in bytes.
4787 FX_DWORD dwPageLeastLen = hStream->GetBits(32);
4788 // Item 5: The number of bits needed to represent the difference
4789 // between the greatest and least length of a page, in bytes.
4790 FX_DWORD dwDeltaPageLenBits = hStream->GetBits(16);
4791 // Skip Item 6, 7, 8, 9 total 96 bits.
4792 hStream->SkipBits(96);
4793 // Item 10: The number of bits needed to represent the greatest
4794 // number of shared object references.
4795 FX_DWORD dwSharedObjBits = hStream->GetBits(16);
4796 // Item 11: The number of bits needed to represent the numerically
4797 // greatest shared object identifier used by the pages.
4798 FX_DWORD dwSharedIdBits = hStream->GetBits(16);
4799 // Item 12: The number of bits needed to represent the numerator of
4800 // the fractional position for each shared object reference. For each
4801 // shared object referenced from a page, there is an indication of
4802 // where in the page's content stream the object is first referenced.
4803 FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16);
4804 // Item 13: Skip Item 13 which has 16 bits.
4805 FX_DWORD dwSharedDenominator = hStream->GetBits(16);
4806 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N"));
4807 int nPages = pPageNum ? pPageNum->GetInteger() : 0;
4808 if (nPages < 1)
4809 return FALSE;
4810 for (int i = 0; i < nPages; ++i) {
4811 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits);
4812 safeDeltaObj += dwObjLeastNum;
4813 if (!safeDeltaObj.IsValid())
4814 return FALSE;
4815 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie());
4816 }
4817 hStream->ByteAlign();
4818 CFX_DWordArray dwPageLenArray;
4819 for (int i = 0; i < nPages; ++i) {
4820 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits);
4821 safePageLen += dwPageLeastLen;
4822 if (!safePageLen.IsValid())
4823 return FALSE;
4824 dwPageLenArray.Add(safePageLen.ValueOrDie());
4825 }
4826 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E"));
4827 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1;
4828 if (nOffsetE < 0)
4829 return FALSE;
4830 CPDF_Object* pFirstPageNum =
4831 m_pLinearizedDict->GetElementValue(FX_BSTRC("P"));
4832 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0;
4833 for (int i = 0; i < nPages; ++i) {
4834 if (i == nFirstPageNum) {
4835 m_szPageOffsetArray.Add(m_szFirstPageObjOffset);
4836 } else if (i == nFirstPageNum + 1) {
4837 if (i == 1) {
4838 m_szPageOffsetArray.Add(nOffsetE);
4839 } else {
4840 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 2] +
4841 dwPageLenArray[i - 2]);
4842 }
4843 } else {
4844 if (i == 0) {
4845 m_szPageOffsetArray.Add(nOffsetE);
4846 } else {
4847 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 1] +
4848 dwPageLenArray[i - 1]);
4849 }
4850 }
4851 }
4852 if (nPages > 0) {
4853 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] +
4854 dwPageLenArray[nPages - 1]);
4855 }
4856 hStream->ByteAlign();
4857 // number of shared objects
4858 for (int i = 0; i < nPages; i++) {
4859 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits));
4860 }
4861 hStream->ByteAlign();
4862 // array of identifier, sizes = nshared_objects
4863 for (int i = 0; i < nPages; i++) {
4864 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) {
4865 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits));
4866 }
4867 }
4868 hStream->ByteAlign();
4869 for (int i = 0; i < nPages; i++) {
4870 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i];
4871 safeSize *= dwSharedNumeratorBits;
4872 if (!safeSize.IsValid())
4873 return FALSE;
4874 hStream->SkipBits(safeSize.ValueOrDie());
4875 }
4876 hStream->ByteAlign();
4877 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages);
4878 safeTotalPageLen *= dwDeltaPageLenBits;
4879 if (!safeTotalPageLen.IsValid())
4880 return FALSE;
4881 hStream->SkipBits(safeTotalPageLen.ValueOrDie());
4882 hStream->ByteAlign();
4883 return TRUE;
4884 }
4885 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream) {
4886 if (!hStream)
4887 return FALSE;
4888 int nStreamOffset = ReadPrimaryHintStreamOffset();
4889 int nStreamLen = ReadPrimaryHintStreamLength();
4890 if (nStreamOffset < 0 || nStreamLen < 1)
4891 return FALSE;
4892 // Item 1: The object number of the first object in the shared objects
4893 // section.
4894 FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32);
4895 // Item 2: The location of the first object in the shared objects section.
4896 FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32);
4897 if (dwFirstSharedObjLoc > nStreamOffset)
4898 dwFirstSharedObjLoc += nStreamLen;
4899 // Item 3: The number of shared object entries for the first page.
4900 m_nFirstPageSharedObjs = hStream->GetBits(32);
4901 // Item 4: The number of shared object entries for the shared objects
4902 // section, including the number of shared object entries for the first page.
4903 FX_DWORD dwSharedObjTotal = hStream->GetBits(32);
4904 // Item 5: The number of bits needed to represent the greatest number of
4905 // objects in a shared object group. Skipped.
4906 hStream->SkipBits(16);
4907 // Item 6: The least length of a shared object group in bytes.
4908 FX_DWORD dwGroupLeastLen = hStream->GetBits(32);
4909 // Item 7: The number of bits needed to represent the difference between the
4910 // greatest and least length of a shared object group, in bytes.
4911 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16);
4912 CPDF_Object* pFirstPageObj =
4913 m_pLinearizedDict->GetElementValue(FX_BSTRC("O"));
4914 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1;
4915 if (nFirstPageObjNum < 0)
4916 return FALSE;
4917 FX_DWORD dwPrevObjLen = 0;
4918 FX_DWORD dwCurObjLen = 0;
4919 for (int i = 0; i < dwSharedObjTotal; ++i) {
4920 dwPrevObjLen = dwCurObjLen;
4921 FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen);
4922 safeObjLen += dwGroupLeastLen;
4923 if (!safeObjLen.IsValid())
4924 return FALSE;
4925 dwCurObjLen = safeObjLen.ValueOrDie();
4926 if (i < m_nFirstPageSharedObjs) {
4927 m_dwSharedObjNumArray.Add(nFirstPageObjNum + i);
4928 if (i == 0)
4929 m_szSharedObjOffsetArray.Add(m_szFirstPageObjOffset);
4930 } else {
4931 FX_SAFE_DWORD safeObjNum = dwFirstSharedObjNum;
4932 safeObjNum += i - m_nFirstPageSharedObjs;
4933 if (!safeObjNum.IsValid())
4934 return FALSE;
4935 m_dwSharedObjNumArray.Add(safeObjNum.ValueOrDie());
4936 if (i == m_nFirstPageSharedObjs)
4937 m_szSharedObjOffsetArray.Add(
4938 pdfium::base::checked_cast<int32_t>(dwFirstSharedObjLoc));
4939 }
4940 if (i != 0 && i != m_nFirstPageSharedObjs) {
4941 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwPrevObjLen);
4942 safeLoc += m_szSharedObjOffsetArray[i - 1];
4943 if (!safeLoc.IsValid())
4944 return FALSE;
4945 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie());
4946 }
4947 }
4948 if (dwSharedObjTotal > 0) {
4949 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwCurObjLen);
4950 safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1];
4951 if (!safeLoc.IsValid())
4952 return FALSE;
4953 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie());
4954 }
4955 hStream->ByteAlign();
4956 hStream->SkipBits(dwSharedObjTotal);
4957 hStream->ByteAlign();
4958 return TRUE;
4959 }
4960 FX_BOOL CPDF_HintTables::GetPagePos(int index,
4961 FX_FILESIZE& szPageStartPos,
4962 FX_FILESIZE& szPageLength,
4963 FX_DWORD& dwObjNum) {
4964 if (!m_pLinearizedDict)
4965 return FALSE;
4966 szPageStartPos = m_szPageOffsetArray[index];
4967 szPageLength = GetItemLength(index, m_szPageOffsetArray);
4968 CPDF_Object* pFirstPageNum =
4969 m_pLinearizedDict->GetElementValue(FX_BSTRC("P"));
4970 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0;
4971 CPDF_Object* pFirstPageObjNum =
4972 m_pLinearizedDict->GetElementValue(FX_BSTRC("O"));
4973 if (!pFirstPageObjNum)
4974 return FALSE;
4975 int nFirstPageObjNum = pFirstPageObjNum->GetInteger();
4976 if (index == nFirstPageNum) {
4977 dwObjNum = nFirstPageObjNum;
4978 return TRUE;
4979 }
4980 // The object number of remaining pages starts from 1.
4981 dwObjNum = 1;
4982 for (int i = 0; i < index; ++i) {
4983 if (i == nFirstPageNum)
4984 continue;
4985 dwObjNum += m_dwDeltaNObjsArray[i];
4986 }
4987 return TRUE;
4988 }
4989 int32_t CPDF_HintTables::CheckPage(int index, IFX_DownloadHints* pHints) {
4990 if (!m_pLinearizedDict || !pHints)
4991 return PDF_DATA_ERROR;
4992 CPDF_Object* pFirstAvailPage =
4993 m_pLinearizedDict->GetElementValue(FX_BSTRC("P"));
4994 int nFirstAvailPage = pFirstAvailPage ? pFirstAvailPage->GetInteger() : 0;
4995 if (index == nFirstAvailPage)
4996 return PDF_DATA_AVAIL;
4997 FX_DWORD dwLength = GetItemLength(index, m_szPageOffsetArray);
4998 if (!dwLength ||
4999 !m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength,
5000 pHints)) {
5001 return PDF_DATA_NOTAVAIL;
5002 }
5003 // Download data of shared objects in the page.
5004 FX_DWORD offset = 0;
5005 for (int i = 0; i < index; ++i) {
5006 offset += m_dwNSharedObjsArray[i];
5007 }
5008 CPDF_Object* pFirstPageObj =
5009 m_pLinearizedDict->GetElementValue(FX_BSTRC("O"));
5010 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1;
5011 if (nFirstPageObjNum < 0)
5012 return FALSE;
5013 FX_DWORD dwIndex = 0;
5014 FX_DWORD dwObjNum = 0;
5015 for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) {
5016 dwIndex = m_dwIdentifierArray[offset + j];
5017 dwObjNum = m_dwSharedObjNumArray[dwIndex];
5018 if (dwObjNum >= nFirstPageObjNum &&
5019 dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) {
5020 continue;
5021 }
5022 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray);
5023 if (!dwLength ||
5024 !m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength,
5025 pHints)) {
5026 return PDF_DATA_NOTAVAIL;
5027 }
5028 }
5029 return PDF_DATA_AVAIL;
5030 }
5031 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) {
5032 if (!pHintStream || !m_pLinearizedDict)
5033 return FALSE;
5034 CPDF_Dictionary* pDict = pHintStream->GetDict();
5035 CPDF_Object* pOffset = pDict ? pDict->GetElement(FX_BSTRC("S")) : nullptr;
5036 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER)
5037 return FALSE;
5038 CPDF_StreamAcc acc;
5039 acc.LoadAllData(pHintStream);
5040 FX_DWORD size = acc.GetSize();
5041 // The header section of page offset hint table is 36 bytes.
5042 // The header section of shared object hint table is 24 bytes.
5043 // Hint table has at least 60 bytes.
5044 const FX_DWORD MIN_STREAM_LEN = 60;
5045 if (size < MIN_STREAM_LEN || size < pOffset->GetInteger() ||
5046 !pOffset->GetInteger()) {
5047 return FALSE;
5048 }
5049 CFX_BitStream bs;
5050 bs.Init(acc.GetData(), size);
5051 return ReadPageHintTable(&bs) && ReadSharedObjHintTable(&bs);
5052 }
5053 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const {
5054 if (!m_pLinearizedDict)
5055 return -1;
5056 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H"));
5057 if (!pRange)
5058 return -1;
5059 CPDF_Object* pStreamOffset = pRange->GetElementValue(0);
5060 if (!pStreamOffset)
5061 return -1;
5062 return pStreamOffset->GetInteger();
5063 }
5064 int CPDF_HintTables::ReadPrimaryHintStreamLength() const {
5065 if (!m_pLinearizedDict)
5066 return -1;
5067 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H"));
5068 if (!pRange)
5069 return -1;
5070 CPDF_Object* pStreamLen = pRange->GetElementValue(1);
5071 if (!pStreamLen)
5072 return -1;
5073 return pStreamLen->GetInteger();
5074 }
OLDNEW
« 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