OLD | NEW |
---|---|
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 "../../../../third_party/base/stl_util.h" | 12 #include "../../../../third_party/base/stl_util.h" |
13 #include "../../../include/fpdfapi/fpdf_module.h" | 13 #include "../../../include/fpdfapi/fpdf_module.h" |
14 #include "../../../include/fpdfapi/fpdf_page.h" | 14 #include "../../../include/fpdfapi/fpdf_page.h" |
15 #include "../../../include/fpdfapi/fpdf_parser.h" | 15 #include "../../../include/fpdfapi/fpdf_parser.h" |
16 #include "../../../include/fxcrt/fx_safe_types.h" | 16 #include "../../../include/fxcrt/fx_safe_types.h" |
17 #include "../fpdf_page/pageint.h" | 17 #include "../fpdf_page/pageint.h" |
18 #include "parser_int.h" | |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 struct SearchTagRecord { | 22 struct SearchTagRecord { |
22 const uint8_t* m_pTag; | 23 const uint8_t* m_pTag; |
23 FX_DWORD m_Len; | 24 FX_DWORD m_Len; |
24 FX_DWORD m_Offset; | 25 FX_DWORD m_Offset; |
25 }; | 26 }; |
26 | 27 |
27 int CompareFileSize(const void* p1, const void* p2) { | 28 int CompareFileSize(const void* p1, const void* p2) { |
(...skipping 2644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2672 } | 2673 } |
2673 buffer[offset++] = ch; | 2674 buffer[offset++] = ch; |
2674 if (offset == size) { | 2675 if (offset == size) { |
2675 break; | 2676 break; |
2676 } | 2677 } |
2677 } | 2678 } |
2678 } | 2679 } |
2679 | 2680 |
2680 class CPDF_DataAvail final : public IPDF_DataAvail { | 2681 class CPDF_DataAvail final : public IPDF_DataAvail { |
2681 public: | 2682 public: |
2682 CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); | 2683 CPDF_DataAvail(IFX_FileAvail* pFileAvail, |
2684 IFX_FileRead* pFileRead, | |
2685 FX_BOOL bSupportHintTable); | |
2683 ~CPDF_DataAvail() override; | 2686 ~CPDF_DataAvail() override; |
2684 | 2687 |
2685 FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; | 2688 int32_t IsDocAvail(IFX_DownloadHints* pHints) override; |
2686 | 2689 |
2687 void SetDocument(CPDF_Document* pDoc) override; | 2690 void SetDocument(CPDF_Document* pDoc) override; |
2688 | 2691 |
2689 FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; | 2692 int32_t IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; |
2690 | 2693 |
2691 int32_t IsFormAvail(IFX_DownloadHints* pHints) override; | 2694 int32_t IsFormAvail(IFX_DownloadHints* pHints) override; |
2692 | 2695 |
2693 int32_t IsLinearizedPDF() override; | 2696 int32_t IsLinearizedPDF() override; |
2694 | 2697 |
2695 FX_BOOL IsLinearized() override { return m_bLinearized; } | 2698 FX_BOOL IsLinearized() override { return m_bLinearized; } |
2696 | 2699 |
2697 void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, FX_DWORD* pSize) override; | 2700 void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, FX_DWORD* pSize) override; |
2701 int GetPageCount() const; | |
2702 CPDF_Dictionary* GetPage(int index); | |
2703 | |
2704 friend class CPDF_HintTables; | |
2698 | 2705 |
2699 protected: | 2706 protected: |
2700 static const int kMaxDataAvailRecursionDepth = 64; | 2707 static const int kMaxDataAvailRecursionDepth = 64; |
2701 static int s_CurrentDataAvailRecursionDepth; | 2708 static int s_CurrentDataAvailRecursionDepth; |
2702 static const int kMaxPageRecursionDepth = 1024; | 2709 static const int kMaxPageRecursionDepth = 1024; |
2703 | 2710 |
2704 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); | 2711 FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); |
2705 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, | 2712 FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, |
2706 FX_BOOL bParsePage, | 2713 FX_BOOL bParsePage, |
2707 IFX_DownloadHints* pHints, | 2714 IFX_DownloadHints* pHints, |
2708 CFX_PtrArray& ret_array); | 2715 CFX_PtrArray& ret_array); |
2709 FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints); | 2716 FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints); |
2710 FX_BOOL CheckHeader(IFX_DownloadHints* pHints); | 2717 FX_BOOL CheckHeader(IFX_DownloadHints* pHints); |
2711 FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints); | 2718 FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints); |
2719 FX_BOOL CheckHintTables(IFX_DownloadHints* pHints); | |
2712 FX_BOOL CheckEnd(IFX_DownloadHints* pHints); | 2720 FX_BOOL CheckEnd(IFX_DownloadHints* pHints); |
2713 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); | 2721 FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); |
2714 FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints); | 2722 FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints); |
2715 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); | 2723 FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); |
2716 FX_BOOL CheckRoot(IFX_DownloadHints* pHints); | 2724 FX_BOOL CheckRoot(IFX_DownloadHints* pHints); |
2717 FX_BOOL CheckInfo(IFX_DownloadHints* pHints); | 2725 FX_BOOL CheckInfo(IFX_DownloadHints* pHints); |
2718 FX_BOOL CheckPages(IFX_DownloadHints* pHints); | 2726 FX_BOOL CheckPages(IFX_DownloadHints* pHints); |
2719 FX_BOOL CheckPage(IFX_DownloadHints* pHints); | 2727 FX_BOOL CheckPage(IFX_DownloadHints* pHints); |
2720 FX_BOOL CheckResources(IFX_DownloadHints* pHints); | 2728 FX_BOOL CheckResources(IFX_DownloadHints* pHints); |
2721 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); | 2729 FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); |
2722 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); | 2730 FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); |
2723 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); | 2731 FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); |
2724 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); | 2732 FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); |
2725 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); | 2733 FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); |
2726 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints); | 2734 FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints); |
2727 | 2735 |
2728 int32_t CheckCrossRefStream(IFX_DownloadHints* pHints, | 2736 int32_t CheckCrossRefStream(IFX_DownloadHints* pHints, |
2729 FX_FILESIZE& xref_offset); | 2737 FX_FILESIZE& xref_offset); |
2730 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); | 2738 FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); |
2731 void SetStartOffset(FX_FILESIZE dwOffset); | 2739 void SetStartOffset(FX_FILESIZE dwOffset); |
2732 FX_BOOL GetNextToken(CFX_ByteString& token); | 2740 FX_BOOL GetNextToken(CFX_ByteString& token); |
2733 FX_BOOL GetNextChar(uint8_t& ch); | 2741 FX_BOOL GetNextChar(uint8_t& ch); |
2734 CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum); | 2742 CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos, |
2743 FX_DWORD objnum, | |
2744 CPDF_IndirectObjects* pObjList = NULL); | |
2735 CPDF_Object* GetObject(FX_DWORD objnum, | 2745 CPDF_Object* GetObject(FX_DWORD objnum, |
2736 IFX_DownloadHints* pHints, | 2746 IFX_DownloadHints* pHints, |
2737 FX_BOOL* pExistInFile); | 2747 FX_BOOL* pExistInFile); |
2738 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); | 2748 FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); |
2739 FX_BOOL PreparePageItem(); | 2749 FX_BOOL PreparePageItem(); |
2740 FX_BOOL LoadPages(IFX_DownloadHints* pHints); | 2750 FX_BOOL LoadPages(IFX_DownloadHints* pHints); |
2741 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); | 2751 FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); |
2742 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); | 2752 FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); |
2743 FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); | 2753 int32_t CheckLinearizedData(IFX_DownloadHints* pHints); |
2744 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); | 2754 FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); |
2745 FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints); | 2755 FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints); |
2746 | 2756 |
2747 FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints); | 2757 FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints); |
2748 FX_BOOL HaveResourceAncestor(CPDF_Dictionary* pDict); | 2758 FX_BOOL HaveResourceAncestor(CPDF_Dictionary* pDict); |
2749 FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHints* pHints); | 2759 FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHints* pHints); |
2750 FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); | 2760 FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); |
2751 FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints); | 2761 FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints); |
2752 FX_BOOL CheckPageNode(CPDF_PageNode& pageNodes, | 2762 FX_BOOL CheckPageNode(CPDF_PageNode& pageNodes, |
2753 int32_t iPage, | 2763 int32_t iPage, |
2754 int32_t& iCount, | 2764 int32_t& iCount, |
2755 IFX_DownloadHints* pHints, | 2765 IFX_DownloadHints* pHints, |
2756 int level); | 2766 int level); |
2757 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, | 2767 FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, |
2758 CPDF_PageNode* pPageNode, | 2768 CPDF_PageNode* pPageNode, |
2759 IFX_DownloadHints* pHints); | 2769 IFX_DownloadHints* pHints); |
2760 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, | 2770 FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, |
2761 CPDF_PageNode* pPageNode, | 2771 CPDF_PageNode* pPageNode, |
2762 IFX_DownloadHints* pHints); | 2772 IFX_DownloadHints* pHints); |
2763 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); | 2773 FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); |
2764 FX_BOOL IsFirstCheck(int iPage); | 2774 FX_BOOL IsFirstCheck(int iPage); |
2765 void ResetFirstCheck(int iPage); | 2775 void ResetFirstCheck(int iPage); |
2776 FX_BOOL IsDataAvail(FX_FILESIZE offset, | |
2777 FX_DWORD size, | |
2778 IFX_DownloadHints* pHints); | |
2766 | 2779 |
2767 CPDF_Parser m_parser; | 2780 CPDF_Parser m_parser; |
2768 | 2781 |
2769 CPDF_SyntaxParser m_syntaxParser; | 2782 CPDF_SyntaxParser m_syntaxParser; |
2770 | 2783 |
2771 CPDF_Object* m_pRoot; | 2784 CPDF_Object* m_pRoot; |
2772 | 2785 |
2773 FX_DWORD m_dwRootObjNum; | 2786 FX_DWORD m_dwRootObjNum; |
2774 | 2787 |
2775 FX_DWORD m_dwInfoObjNum; | 2788 FX_DWORD m_dwInfoObjNum; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2869 FX_FILESIZE m_dwPrevXRefOffset; | 2882 FX_FILESIZE m_dwPrevXRefOffset; |
2870 | 2883 |
2871 FX_BOOL m_bTotalLoadPageTree; | 2884 FX_BOOL m_bTotalLoadPageTree; |
2872 | 2885 |
2873 FX_BOOL m_bCurPageDictLoadOK; | 2886 FX_BOOL m_bCurPageDictLoadOK; |
2874 | 2887 |
2875 CPDF_PageNode m_pageNodes; | 2888 CPDF_PageNode m_pageNodes; |
2876 | 2889 |
2877 std::set<FX_DWORD> m_pageMapCheckState; | 2890 std::set<FX_DWORD> m_pageMapCheckState; |
2878 std::set<FX_DWORD> m_pagesLoadState; | 2891 std::set<FX_DWORD> m_pagesLoadState; |
2892 | |
2893 nonstd::unique_ptr<CPDF_HintTables> m_pHintTables; | |
2894 FX_BOOL m_bSupportHintTable; | |
2879 }; | 2895 }; |
2880 | 2896 |
2881 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, | 2897 IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, |
2882 IFX_FileRead* pFileRead) | 2898 IFX_FileRead* pFileRead) |
2883 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} | 2899 : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} |
2884 | 2900 |
2885 // static | 2901 // static |
2886 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, | 2902 IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, |
2887 IFX_FileRead* pFileRead) { | 2903 IFX_FileRead* pFileRead) { |
2888 return new CPDF_DataAvail(pFileAvail, pFileRead); | 2904 return new CPDF_DataAvail(pFileAvail, pFileRead, TRUE); |
2889 } | 2905 } |
2890 | 2906 |
2891 // static | 2907 // static |
2892 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; | 2908 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; |
2893 | 2909 |
2894 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, | 2910 CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, |
2895 IFX_FileRead* pFileRead) | 2911 IFX_FileRead* pFileRead, |
2912 FX_BOOL bSupportHintTable) | |
2896 : IPDF_DataAvail(pFileAvail, pFileRead) { | 2913 : IPDF_DataAvail(pFileAvail, pFileRead) { |
2897 m_Pos = 0; | 2914 m_Pos = 0; |
2898 m_dwFileLen = 0; | 2915 m_dwFileLen = 0; |
2899 if (m_pFileRead) { | 2916 if (m_pFileRead) { |
2900 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); | 2917 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); |
2901 } | 2918 } |
2902 m_dwCurrentOffset = 0; | 2919 m_dwCurrentOffset = 0; |
2903 m_WordSize = 0; | 2920 m_WordSize = 0; |
2904 m_dwXRefOffset = 0; | 2921 m_dwXRefOffset = 0; |
2905 m_bufferOffset = 0; | 2922 m_bufferOffset = 0; |
(...skipping 25 matching lines...) Expand all Loading... | |
2931 m_pTrailer = NULL; | 2948 m_pTrailer = NULL; |
2932 m_pCurrentParser = NULL; | 2949 m_pCurrentParser = NULL; |
2933 m_pAcroForm = NULL; | 2950 m_pAcroForm = NULL; |
2934 m_pPageDict = NULL; | 2951 m_pPageDict = NULL; |
2935 m_pPageResource = NULL; | 2952 m_pPageResource = NULL; |
2936 m_docStatus = PDF_DATAAVAIL_HEADER; | 2953 m_docStatus = PDF_DATAAVAIL_HEADER; |
2937 m_parser.m_bOwnFileRead = FALSE; | 2954 m_parser.m_bOwnFileRead = FALSE; |
2938 m_bTotalLoadPageTree = FALSE; | 2955 m_bTotalLoadPageTree = FALSE; |
2939 m_bCurPageDictLoadOK = FALSE; | 2956 m_bCurPageDictLoadOK = FALSE; |
2940 m_bLinearedDataOK = FALSE; | 2957 m_bLinearedDataOK = FALSE; |
2958 m_bSupportHintTable = bSupportHintTable; | |
2941 } | 2959 } |
2942 CPDF_DataAvail::~CPDF_DataAvail() { | 2960 CPDF_DataAvail::~CPDF_DataAvail() { |
2943 if (m_pLinearized) { | 2961 if (m_pLinearized) { |
2944 m_pLinearized->Release(); | 2962 m_pLinearized->Release(); |
2945 } | 2963 } |
2946 if (m_pRoot) { | 2964 if (m_pRoot) { |
2947 m_pRoot->Release(); | 2965 m_pRoot->Release(); |
2948 } | 2966 } |
2949 if (m_pTrailer) { | 2967 if (m_pTrailer) { |
2950 m_pTrailer->Release(); | 2968 m_pTrailer->Release(); |
2951 } | 2969 } |
2952 int32_t i = 0; | 2970 |
2953 int32_t iSize = m_arrayAcroforms.GetSize(); | 2971 int32_t iSize = m_arrayAcroforms.GetSize(); |
2954 for (i = 0; i < iSize; ++i) { | 2972 for (int i = 0; i < iSize; ++i) { |
Tom Sepez
2015/10/29 16:20:17
nit: might as well be int32_t if iSize is as well.
| |
2955 static_cast<CPDF_Object*>(m_arrayAcroforms.GetAt(i))->Release(); | 2973 ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release(); |
Tom Sepez
2015/10/29 16:20:17
Why did we change the static cast? Looks like some
jun_fang
2015/10/30 06:02:43
It was introduced in conflicting resolved. I notic
| |
2956 } | 2974 } |
2957 } | 2975 } |
2958 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { | 2976 void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { |
2959 m_pDocument = pDoc; | 2977 m_pDocument = pDoc; |
2960 } | 2978 } |
2961 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { | 2979 FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { |
2962 CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser()); | 2980 CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser()); |
2963 if (pParser == NULL) { | 2981 if (pParser == NULL) { |
2964 return 0; | 2982 return 0; |
2965 } | 2983 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3026 value = pDict->GetNextElement(pos, key); | 3044 value = pDict->GetNextElement(pos, key); |
3027 if (key != "Parent") { | 3045 if (key != "Parent") { |
3028 new_obj_array.Add(value); | 3046 new_obj_array.Add(value); |
3029 } | 3047 } |
3030 } | 3048 } |
3031 } break; | 3049 } break; |
3032 case PDFOBJ_REFERENCE: { | 3050 case PDFOBJ_REFERENCE: { |
3033 CPDF_Reference* pRef = pObj->AsReference(); | 3051 CPDF_Reference* pRef = pObj->AsReference(); |
3034 FX_DWORD dwNum = pRef->GetRefObjNum(); | 3052 FX_DWORD dwNum = pRef->GetRefObjNum(); |
3035 FX_FILESIZE offset; | 3053 FX_FILESIZE offset; |
3036 FX_DWORD original_size = GetObjectSize(dwNum, offset); | 3054 FX_DWORD size = GetObjectSize(dwNum, offset); |
3037 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; | 3055 if (size == 0 || offset < 0 || offset >= m_dwFileLen) { |
3038 if (size.ValueOrDefault(0) == 0 || offset < 0 || | |
3039 offset >= m_dwFileLen) { | |
3040 break; | 3056 break; |
3041 } | 3057 } |
3042 | 3058 if (!IsDataAvail(offset, size, pHints)) { |
3043 size += offset; | |
3044 size += 512; | |
3045 if (!size.IsValid()) { | |
3046 break; | |
3047 } | |
3048 if (size.ValueOrDie() > m_dwFileLen) { | |
3049 size = m_dwFileLen - offset; | |
3050 } else { | |
3051 size = original_size + 512; | |
3052 } | |
3053 if (!size.IsValid()) { | |
3054 break; | |
3055 } | |
3056 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { | |
3057 pHints->AddSegment(offset, size.ValueOrDie()); | |
3058 ret_array.Add(pObj); | 3059 ret_array.Add(pObj); |
3059 count++; | 3060 count++; |
3060 } else if (!m_objnum_array.Find(dwNum)) { | 3061 } else if (!m_objnum_array.Find(dwNum)) { |
3061 m_objnum_array.AddObjNum(dwNum); | 3062 m_objnum_array.AddObjNum(dwNum); |
3062 CPDF_Object* pReferred = | 3063 CPDF_Object* pReferred = |
3063 m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL); | 3064 m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL); |
3064 if (pReferred) { | 3065 if (pReferred) { |
3065 new_obj_array.Add(pReferred); | 3066 new_obj_array.Add(pReferred); |
3066 } | 3067 } |
3067 } | 3068 } |
(...skipping 11 matching lines...) Expand all Loading... | |
3079 } else { | 3080 } else { |
3080 ret_array.Add(pObj); | 3081 ret_array.Add(pObj); |
3081 } | 3082 } |
3082 } | 3083 } |
3083 return FALSE; | 3084 return FALSE; |
3084 } | 3085 } |
3085 obj_array.RemoveAll(); | 3086 obj_array.RemoveAll(); |
3086 obj_array.Append(new_obj_array); | 3087 obj_array.Append(new_obj_array); |
3087 return IsObjectsAvail(obj_array, FALSE, pHints, ret_array); | 3088 return IsObjectsAvail(obj_array, FALSE, pHints, ret_array); |
3088 } | 3089 } |
3089 FX_BOOL CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints) { | 3090 int32_t CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints) { |
3090 if (!m_dwFileLen && m_pFileRead) { | 3091 if (!m_dwFileLen && m_pFileRead) { |
3091 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); | 3092 m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); |
3092 if (!m_dwFileLen) { | 3093 if (!m_dwFileLen) { |
3093 return TRUE; | 3094 return PDF_DATA_ERROR; |
3094 } | 3095 } |
3095 } | 3096 } |
3096 while (!m_bDocAvail) { | 3097 while (!m_bDocAvail) { |
3097 if (!CheckDocStatus(pHints)) { | 3098 if (!CheckDocStatus(pHints)) { |
3098 return FALSE; | 3099 return PDF_DATA_NOTAVAIL; |
3099 } | 3100 } |
3100 } | 3101 } |
3101 return TRUE; | 3102 return PDF_DATA_AVAIL; |
3102 } | 3103 } |
3103 FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) { | 3104 FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) { |
3104 if (!m_objs_array.GetSize()) { | 3105 if (!m_objs_array.GetSize()) { |
3105 m_objs_array.RemoveAll(); | 3106 m_objs_array.RemoveAll(); |
3106 m_objnum_array.RemoveAll(); | 3107 m_objnum_array.RemoveAll(); |
3107 CFX_PtrArray obj_array; | 3108 CFX_PtrArray obj_array; |
3108 obj_array.Append(m_arrayAcroforms); | 3109 obj_array.Append(m_arrayAcroforms); |
3109 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); | 3110 FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); |
3110 if (bRet) { | 3111 if (bRet) { |
3111 m_objs_array.RemoveAll(); | 3112 m_objs_array.RemoveAll(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3144 m_docStatus = PDF_DATAAVAIL_PAGETREE; | 3145 m_docStatus = PDF_DATAAVAIL_PAGETREE; |
3145 return TRUE; | 3146 return TRUE; |
3146 } | 3147 } |
3147 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { | 3148 FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { |
3148 switch (m_docStatus) { | 3149 switch (m_docStatus) { |
3149 case PDF_DATAAVAIL_HEADER: | 3150 case PDF_DATAAVAIL_HEADER: |
3150 return CheckHeader(pHints); | 3151 return CheckHeader(pHints); |
3151 case PDF_DATAAVAIL_FIRSTPAGE: | 3152 case PDF_DATAAVAIL_FIRSTPAGE: |
3152 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: | 3153 case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: |
3153 return CheckFirstPage(pHints); | 3154 return CheckFirstPage(pHints); |
3155 case PDF_DATAAVAIL_HINTTABLE: | |
3156 return CheckHintTables(pHints); | |
3154 case PDF_DATAAVAIL_END: | 3157 case PDF_DATAAVAIL_END: |
3155 return CheckEnd(pHints); | 3158 return CheckEnd(pHints); |
3156 case PDF_DATAAVAIL_CROSSREF: | 3159 case PDF_DATAAVAIL_CROSSREF: |
3157 return CheckCrossRef(pHints); | 3160 return CheckCrossRef(pHints); |
3158 case PDF_DATAAVAIL_CROSSREF_ITEM: | 3161 case PDF_DATAAVAIL_CROSSREF_ITEM: |
3159 return CheckCrossRefItem(pHints); | 3162 return CheckCrossRefItem(pHints); |
3160 case PDF_DATAAVAIL_CROSSREF_STREAM: | 3163 case PDF_DATAAVAIL_CROSSREF_STREAM: |
3161 return CheckAllCrossRefStream(pHints); | 3164 return CheckAllCrossRefStream(pHints); |
3162 case PDF_DATAAVAIL_TRAILER: | 3165 case PDF_DATAAVAIL_TRAILER: |
3163 return CheckTrailer(pHints); | 3166 return CheckTrailer(pHints); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3228 CompareFileSize); | 3231 CompareFileSize); |
3229 m_dwRootObjNum = m_parser.GetRootObjNum(); | 3232 m_dwRootObjNum = m_parser.GetRootObjNum(); |
3230 m_dwInfoObjNum = m_parser.GetInfoObjNum(); | 3233 m_dwInfoObjNum = m_parser.GetInfoObjNum(); |
3231 m_pCurrentParser = &m_parser; | 3234 m_pCurrentParser = &m_parser; |
3232 m_docStatus = PDF_DATAAVAIL_ROOT; | 3235 m_docStatus = PDF_DATAAVAIL_ROOT; |
3233 return TRUE; | 3236 return TRUE; |
3234 } | 3237 } |
3235 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, | 3238 CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, |
3236 IFX_DownloadHints* pHints, | 3239 IFX_DownloadHints* pHints, |
3237 FX_BOOL* pExistInFile) { | 3240 FX_BOOL* pExistInFile) { |
3238 CPDF_Object* pRet = NULL; | 3241 CPDF_Object* pRet = nullptr; |
3239 FX_DWORD original_size = 0; | 3242 FX_DWORD size = 0; |
3240 FX_FILESIZE offset = 0; | 3243 FX_FILESIZE offset = 0; |
3241 CPDF_Parser* pParser = NULL; | 3244 CPDF_Parser* pParser = nullptr; |
3242 | 3245 if (pExistInFile) |
3243 if (pExistInFile) { | |
3244 *pExistInFile = TRUE; | 3246 *pExistInFile = TRUE; |
3245 } | |
3246 | 3247 |
3247 if (m_pDocument == NULL) { | 3248 if (m_pDocument == NULL) { |
3248 original_size = (FX_DWORD)m_parser.GetObjectSize(objnum); | 3249 size = (FX_DWORD)m_parser.GetObjectSize(objnum); |
3249 offset = m_parser.GetObjectOffset(objnum); | 3250 offset = m_parser.GetObjectOffset(objnum); |
3250 pParser = &m_parser; | 3251 pParser = &m_parser; |
3251 } else { | 3252 } else { |
3252 original_size = GetObjectSize(objnum, offset); | 3253 size = GetObjectSize(objnum, offset); |
3253 pParser = (CPDF_Parser*)(m_pDocument->GetParser()); | 3254 pParser = (CPDF_Parser*)(m_pDocument->GetParser()); |
3254 } | 3255 } |
3255 | 3256 if (!IsDataAvail(offset, size, pHints)) { |
3256 pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; | 3257 return nullptr; |
3257 if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) { | |
3258 if (pExistInFile) | |
3259 *pExistInFile = FALSE; | |
3260 | |
3261 return NULL; | |
3262 } | 3258 } |
3263 | |
3264 size += offset; | |
3265 size += 512; | |
3266 if (!size.IsValid()) { | |
3267 return NULL; | |
3268 } | |
3269 | |
3270 if (size.ValueOrDie() > m_dwFileLen) { | |
3271 size = m_dwFileLen - offset; | |
3272 } else { | |
3273 size = original_size + 512; | |
3274 } | |
3275 | |
3276 if (!size.IsValid()) { | |
3277 return NULL; | |
3278 } | |
3279 | |
3280 if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { | |
3281 pHints->AddSegment(offset, size.ValueOrDie()); | |
3282 return NULL; | |
3283 } | |
3284 | |
3285 if (pParser) { | 3259 if (pParser) { |
3286 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); | 3260 pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); |
3287 } | 3261 } |
3288 | 3262 |
3289 if (!pRet && pExistInFile) { | 3263 if (!pRet && pExistInFile) { |
3290 *pExistInFile = FALSE; | 3264 *pExistInFile = FALSE; |
3291 } | 3265 } |
3292 | 3266 |
3293 return pRet; | 3267 return pRet; |
3294 } | 3268 } |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3569 FX_FILESIZE offset = m_dwLastXRefOffset; | 3543 FX_FILESIZE offset = m_dwLastXRefOffset; |
3570 if (dwSize < 512 && dwFileLen > 512) { | 3544 if (dwSize < 512 && dwFileLen > 512) { |
3571 dwSize = 512; | 3545 dwSize = 512; |
3572 offset = dwFileLen - 512; | 3546 offset = dwFileLen - 512; |
3573 } | 3547 } |
3574 pHints->AddSegment(offset, dwSize); | 3548 pHints->AddSegment(offset, dwSize); |
3575 } | 3549 } |
3576 } else { | 3550 } else { |
3577 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; | 3551 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; |
3578 } | 3552 } |
3579 if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { | 3553 if (bNeedDownLoad || m_docStatus != PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { |
3554 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; | |
3555 return FALSE; | |
3556 } | |
3557 m_docStatus = | |
3558 m_bSupportHintTable ? PDF_DATAAVAIL_HINTTABLE : PDF_DATAAVAIL_DONE; | |
3559 return TRUE; | |
3560 } | |
3561 FX_BOOL CPDF_DataAvail::IsDataAvail(FX_FILESIZE offset, | |
3562 FX_DWORD size, | |
3563 IFX_DownloadHints* pHints) { | |
3564 if (offset > m_dwFileLen) | |
3565 return TRUE; | |
3566 FX_SAFE_DWORD safeSize = pdfium::base::checked_cast<FX_DWORD>(offset); | |
3567 safeSize += size; | |
3568 safeSize += 512; | |
3569 if (!safeSize.IsValid() || safeSize.ValueOrDie() > m_dwFileLen) | |
3570 size = m_dwFileLen - offset; | |
3571 else | |
3572 size += 512; | |
3573 if (!m_pFileAvail->IsDataAvail(offset, size)) { | |
3574 pHints->AddSegment(offset, size); | |
3575 return FALSE; | |
3576 } | |
3577 return TRUE; | |
3578 } | |
3579 FX_BOOL CPDF_DataAvail::CheckHintTables(IFX_DownloadHints* pHints) { | |
3580 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); | |
3581 if (!pDict) { | |
3582 m_docStatus = PDF_DATAAVAIL_ERROR; | |
3583 return FALSE; | |
3584 } | |
3585 if (!pDict->KeyExist(FX_BSTRC("H")) || !pDict->KeyExist(FX_BSTRC("O")) || | |
3586 !pDict->KeyExist(FX_BSTRC("N"))) { | |
3587 m_docStatus = PDF_DATAAVAIL_ERROR; | |
3588 return FALSE; | |
3589 } | |
3590 int nPageCount = pDict->GetElementValue(FX_BSTRC("N"))->GetInteger(); | |
3591 if (nPageCount <= 1) { | |
3580 m_docStatus = PDF_DATAAVAIL_DONE; | 3592 m_docStatus = PDF_DATAAVAIL_DONE; |
3581 return TRUE; | 3593 return TRUE; |
3582 } | 3594 } |
3583 m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; | 3595 CPDF_Array* pHintStreamRange = pDict->GetArray(FX_BSTRC("H")); |
3584 return FALSE; | 3596 FX_FILESIZE szHSStart = |
3597 pHintStreamRange->GetElementValue(0) | |
3598 ? pHintStreamRange->GetElementValue(0)->GetInteger() | |
3599 : 0; | |
3600 FX_FILESIZE szHSLength = | |
3601 pHintStreamRange->GetElementValue(1) | |
3602 ? pHintStreamRange->GetElementValue(1)->GetInteger() | |
3603 : 0; | |
3604 if (szHSStart < 0 || szHSLength <= 0) { | |
3605 m_docStatus = PDF_DATAAVAIL_ERROR; | |
3606 return FALSE; | |
3607 } | |
3608 if (!IsDataAvail(szHSStart, szHSLength, pHints)) { | |
3609 return FALSE; | |
3610 } | |
3611 m_syntaxParser.InitParser(m_pFileRead, m_dwHeaderOffset); | |
3612 nonstd::unique_ptr<CPDF_HintTables> pHintTables( | |
3613 new CPDF_HintTables(this, pDict)); | |
3614 CPDF_Stream* pHintStream = (CPDF_Stream*)ParseIndirectObjectAt(szHSStart, 0); | |
3615 FX_BOOL bLoaded = FALSE; | |
3616 if (pHintTables && pHintStream && pHintStream->GetType() == PDFOBJ_STREAM) { | |
3617 bLoaded = pHintTables->LoadHintStream(pHintStream); | |
3618 } | |
3619 if (!bLoaded) { | |
3620 m_pHintTables.reset(pHintTables.release()); | |
3621 } | |
3622 m_docStatus = PDF_DATAAVAIL_DONE; | |
3623 return TRUE; | |
3585 } | 3624 } |
3586 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, | 3625 CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt( |
3587 FX_DWORD objnum) { | 3626 FX_FILESIZE pos, |
3627 FX_DWORD objnum, | |
3628 CPDF_IndirectObjects* pObjList) { | |
3588 FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); | 3629 FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); |
3589 m_syntaxParser.RestorePos(pos); | 3630 m_syntaxParser.RestorePos(pos); |
3590 FX_BOOL bIsNumber; | 3631 FX_BOOL bIsNumber; |
3591 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); | 3632 CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); |
3592 if (!bIsNumber) { | 3633 if (!bIsNumber) { |
3593 return NULL; | 3634 return NULL; |
3594 } | 3635 } |
3595 FX_DWORD parser_objnum = FXSYS_atoi(word); | 3636 FX_DWORD parser_objnum = FXSYS_atoi(word); |
3596 if (objnum && parser_objnum != objnum) { | 3637 if (objnum && parser_objnum != objnum) { |
3597 return NULL; | 3638 return NULL; |
3598 } | 3639 } |
3599 word = m_syntaxParser.GetNextWord(bIsNumber); | 3640 word = m_syntaxParser.GetNextWord(bIsNumber); |
3600 if (!bIsNumber) { | 3641 if (!bIsNumber) { |
3601 return NULL; | 3642 return NULL; |
3602 } | 3643 } |
3603 FX_DWORD gennum = FXSYS_atoi(word); | 3644 FX_DWORD gennum = FXSYS_atoi(word); |
3604 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { | 3645 if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { |
3605 m_syntaxParser.RestorePos(SavedPos); | 3646 m_syntaxParser.RestorePos(SavedPos); |
3606 return NULL; | 3647 return NULL; |
3607 } | 3648 } |
3608 CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0); | 3649 CPDF_Object* pObj = |
3650 m_syntaxParser.GetObject(pObjList, parser_objnum, gennum, 0); | |
3609 m_syntaxParser.RestorePos(SavedPos); | 3651 m_syntaxParser.RestorePos(SavedPos); |
3610 return pObj; | 3652 return pObj; |
3611 } | 3653 } |
3612 int32_t CPDF_DataAvail::IsLinearizedPDF() { | 3654 int32_t CPDF_DataAvail::IsLinearizedPDF() { |
3613 FX_DWORD req_size = 1024; | 3655 FX_DWORD req_size = 1024; |
3614 if (!m_pFileAvail->IsDataAvail(0, req_size)) { | 3656 if (!m_pFileAvail->IsDataAvail(0, req_size)) { |
3615 return PDF_UNKNOW_LINEARIZED; | 3657 return PDF_LINEARIZATION_UNKNOWN; |
3616 } | 3658 } |
3617 if (!m_pFileRead) { | 3659 if (!m_pFileRead) { |
3618 return PDF_NOT_LINEARIZED; | 3660 return PDF_NOT_LINEARIZED; |
3619 } | 3661 } |
3620 FX_FILESIZE dwSize = m_pFileRead->GetSize(); | 3662 FX_FILESIZE dwSize = m_pFileRead->GetSize(); |
3621 if (dwSize < (FX_FILESIZE)req_size) { | 3663 if (dwSize < (FX_FILESIZE)req_size) { |
3622 return PDF_UNKNOW_LINEARIZED; | 3664 return PDF_LINEARIZATION_UNKNOWN; |
3623 } | 3665 } |
3624 uint8_t buffer[1024]; | 3666 uint8_t buffer[1024]; |
3625 m_pFileRead->ReadBlock(buffer, 0, req_size); | 3667 m_pFileRead->ReadBlock(buffer, 0, req_size); |
3626 if (IsLinearizedFile(buffer, req_size)) { | 3668 if (IsLinearizedFile(buffer, req_size)) { |
3627 return PDF_IS_LINEARIZED; | 3669 return PDF_LINEARIZED; |
3628 } | 3670 } |
3629 return PDF_NOT_LINEARIZED; | 3671 return PDF_NOT_LINEARIZED; |
3630 } | 3672 } |
3631 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { | 3673 FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { |
3632 ScopedFileStream file(FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); | 3674 ScopedFileStream file(FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); |
3633 int32_t offset = GetHeaderOffset(file.get()); | 3675 int32_t offset = GetHeaderOffset(file.get()); |
3634 if (offset == -1) { | 3676 if (offset == -1) { |
3635 m_docStatus = PDF_DATAAVAIL_ERROR; | 3677 m_docStatus = PDF_DATAAVAIL_ERROR; |
3636 return FALSE; | 3678 return FALSE; |
3637 } | 3679 } |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4234 if (!CheckPageStatus(pHints)) { | 4276 if (!CheckPageStatus(pHints)) { |
4235 return FALSE; | 4277 return FALSE; |
4236 } | 4278 } |
4237 } | 4279 } |
4238 if (m_bPagesLoad) { | 4280 if (m_bPagesLoad) { |
4239 return TRUE; | 4281 return TRUE; |
4240 } | 4282 } |
4241 m_pDocument->LoadPages(); | 4283 m_pDocument->LoadPages(); |
4242 return FALSE; | 4284 return FALSE; |
4243 } | 4285 } |
4244 FX_BOOL CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints) { | 4286 int32_t CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints) { |
4245 if (m_bLinearedDataOK) { | 4287 if (m_bLinearedDataOK) { |
4246 return TRUE; | 4288 return PDF_DATA_AVAIL; |
4247 } | 4289 } |
4248 | 4290 |
4249 if (!m_bMainXRefLoadTried) { | 4291 if (!m_bMainXRefLoadTried) { |
4250 FX_SAFE_DWORD data_size = m_dwFileLen; | 4292 FX_SAFE_DWORD data_size = m_dwFileLen; |
4251 data_size -= m_dwLastXRefOffset; | 4293 data_size -= m_dwLastXRefOffset; |
4252 if (!data_size.IsValid()) { | 4294 if (!data_size.IsValid()) { |
4253 return FALSE; | 4295 return PDF_DATA_ERROR; |
4254 } | 4296 } |
4255 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, | 4297 if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, |
4256 data_size.ValueOrDie())) { | 4298 data_size.ValueOrDie())) { |
4257 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie()); | 4299 pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie()); |
4258 return FALSE; | 4300 return PDF_DATA_NOTAVAIL; |
4259 } | 4301 } |
4260 FX_DWORD dwRet = | 4302 FX_DWORD dwRet = (m_pDocument->GetParser())->LoadLinearizedMainXRefTable(); |
4261 ((CPDF_Parser*)m_pDocument->GetParser())->LoadLinearizedMainXRefTable(); | |
4262 m_bMainXRefLoadTried = TRUE; | 4303 m_bMainXRefLoadTried = TRUE; |
4263 if (dwRet != PDFPARSE_ERROR_SUCCESS) { | 4304 if (dwRet != PDFPARSE_ERROR_SUCCESS) { |
4264 return FALSE; | 4305 return PDF_DATA_ERROR; |
4265 } | 4306 } |
4266 if (!PreparePageItem()) { | 4307 if (!PreparePageItem()) { |
4267 return FALSE; | 4308 return PDF_DATA_NOTAVAIL; |
4268 } | 4309 } |
4269 m_bMainXRefLoadedOK = TRUE; | 4310 m_bMainXRefLoadedOK = TRUE; |
4270 m_bLinearedDataOK = TRUE; | 4311 m_bLinearedDataOK = TRUE; |
4271 } | 4312 } |
4272 | 4313 |
4273 return m_bLinearedDataOK; | 4314 return m_bLinearedDataOK ? PDF_DATA_AVAIL : PDF_DATA_NOTAVAIL; |
4274 } | 4315 } |
4275 FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage, | 4316 FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage, |
4276 IFX_DownloadHints* pHints) { | 4317 IFX_DownloadHints* pHints) { |
4277 if (!m_objs_array.GetSize()) { | 4318 if (!m_objs_array.GetSize()) { |
4278 m_objs_array.RemoveAll(); | 4319 m_objs_array.RemoveAll(); |
4279 m_objnum_array.RemoveAll(); | 4320 m_objnum_array.RemoveAll(); |
4280 CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iPage); | 4321 CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iPage); |
4281 if (!pPageDict) { | 4322 if (!pPageDict) { |
4282 return TRUE; | 4323 return TRUE; |
4283 } | 4324 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4329 if (!pParentDict) { | 4370 if (!pParentDict) { |
4330 return FALSE; | 4371 return FALSE; |
4331 } | 4372 } |
4332 CPDF_Object* pRet = pParentDict->GetElement("Resources"); | 4373 CPDF_Object* pRet = pParentDict->GetElement("Resources"); |
4333 if (pRet) { | 4374 if (pRet) { |
4334 m_pPageResource = pRet; | 4375 m_pPageResource = pRet; |
4335 return TRUE; | 4376 return TRUE; |
4336 } | 4377 } |
4337 return HaveResourceAncestor(pParentDict); | 4378 return HaveResourceAncestor(pParentDict); |
4338 } | 4379 } |
4339 FX_BOOL CPDF_DataAvail::IsPageAvail(int32_t iPage, IFX_DownloadHints* pHints) { | 4380 int32_t CPDF_DataAvail::IsPageAvail(int32_t iPage, IFX_DownloadHints* pHints) { |
4340 if (!m_pDocument) { | 4381 if (!m_pDocument) { |
4341 return FALSE; | 4382 return PDF_DATA_ERROR; |
4342 } | 4383 } |
4343 if (IsFirstCheck(iPage)) { | 4384 if (IsFirstCheck(iPage)) { |
4344 m_bCurPageDictLoadOK = FALSE; | 4385 m_bCurPageDictLoadOK = FALSE; |
4345 m_bPageLoadedOK = FALSE; | 4386 m_bPageLoadedOK = FALSE; |
4346 m_bAnnotsLoad = FALSE; | 4387 m_bAnnotsLoad = FALSE; |
4347 m_bNeedDownLoadResource = FALSE; | 4388 m_bNeedDownLoadResource = FALSE; |
4348 m_objs_array.RemoveAll(); | 4389 m_objs_array.RemoveAll(); |
4349 m_objnum_array.RemoveAll(); | 4390 m_objnum_array.RemoveAll(); |
4350 } | 4391 } |
4351 if (m_pagesLoadState.find(iPage) != m_pagesLoadState.end()) { | 4392 if (m_pagesLoadState.find(iPage) != m_pagesLoadState.end()) { |
4352 return TRUE; | 4393 return PDF_DATA_AVAIL; |
4353 } | 4394 } |
4354 if (m_bLinearized) { | 4395 if (m_bLinearized) { |
4355 if ((FX_DWORD)iPage == m_dwFirstPageNo) { | 4396 if ((FX_DWORD)iPage == m_dwFirstPageNo) { |
4356 m_pagesLoadState.insert(iPage); | 4397 m_pagesLoadState.insert(iPage); |
4357 return TRUE; | 4398 return PDF_DATA_AVAIL; |
4358 } | 4399 } |
4359 if (!CheckLinearizedData(pHints)) { | 4400 int32_t nResult = CheckLinearizedData(pHints); |
4360 return FALSE; | 4401 if (nResult != PDF_DATA_AVAIL) { |
4402 return nResult; | |
4403 } | |
4404 if (m_pHintTables) { | |
4405 nResult = m_pHintTables->CheckPage(iPage, pHints); | |
4406 if (nResult != PDF_DATA_AVAIL) | |
4407 return nResult; | |
4408 m_pagesLoadState.insert(iPage); | |
4409 return PDF_DATA_AVAIL; | |
4361 } | 4410 } |
4362 if (m_bMainXRefLoadedOK) { | 4411 if (m_bMainXRefLoadedOK) { |
4363 if (m_bTotalLoadPageTree) { | 4412 if (m_bTotalLoadPageTree) { |
4364 if (!LoadPages(pHints)) { | 4413 if (!LoadPages(pHints)) { |
4365 return FALSE; | 4414 return PDF_DATA_NOTAVAIL; |
4366 } | 4415 } |
4367 } else { | 4416 } else { |
4368 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { | 4417 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { |
4369 return FALSE; | 4418 return PDF_DATA_NOTAVAIL; |
4370 } | 4419 } |
4371 } | 4420 } |
4372 } else { | 4421 } else { |
4373 if (!LoadAllFile(pHints)) { | 4422 if (!LoadAllFile(pHints)) { |
4374 return FALSE; | 4423 return PDF_DATA_NOTAVAIL; |
4375 } | 4424 } |
4376 ((CPDF_Parser*)m_pDocument->GetParser())->RebuildCrossRef(); | 4425 ((CPDF_Parser*)m_pDocument->GetParser())->RebuildCrossRef(); |
4377 ResetFirstCheck(iPage); | 4426 ResetFirstCheck(iPage); |
4378 return TRUE; | 4427 return PDF_DATA_AVAIL; |
4379 } | 4428 } |
4380 } else { | 4429 } else { |
4381 if (!m_bTotalLoadPageTree) { | 4430 if (!m_bTotalLoadPageTree) { |
4382 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { | 4431 if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { |
4383 return FALSE; | 4432 return PDF_DATA_NOTAVAIL; |
4384 } | 4433 } |
4385 } | 4434 } |
4386 } | 4435 } |
4387 if (m_bHaveAcroForm && !m_bAcroFormLoad) { | 4436 if (m_bHaveAcroForm && !m_bAcroFormLoad) { |
4388 if (!CheckAcroFormSubObject(pHints)) { | 4437 if (!CheckAcroFormSubObject(pHints)) { |
4389 return FALSE; | 4438 return PDF_DATA_NOTAVAIL; |
4390 } | 4439 } |
4391 m_bAcroFormLoad = TRUE; | 4440 m_bAcroFormLoad = TRUE; |
4392 } | 4441 } |
4393 if (!m_bPageLoadedOK) { | 4442 if (!m_bPageLoadedOK) { |
4394 if (!m_objs_array.GetSize()) { | 4443 if (!m_objs_array.GetSize()) { |
4395 m_objs_array.RemoveAll(); | 4444 m_objs_array.RemoveAll(); |
4396 m_objnum_array.RemoveAll(); | 4445 m_objnum_array.RemoveAll(); |
4397 m_pPageDict = m_pDocument->GetPage(iPage); | 4446 m_pPageDict = m_pDocument->GetPage(iPage); |
4398 if (!m_pPageDict) { | 4447 if (!m_pPageDict) { |
4399 ResetFirstCheck(iPage); | 4448 ResetFirstCheck(iPage); |
4400 return TRUE; | 4449 return PDF_DATA_AVAIL; |
4401 } | 4450 } |
4402 CFX_PtrArray obj_array; | 4451 CFX_PtrArray obj_array; |
4403 obj_array.Add(m_pPageDict); | 4452 obj_array.Add(m_pPageDict); |
4404 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); | 4453 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); |
4405 if (bRet) { | 4454 if (bRet) { |
4406 m_objs_array.RemoveAll(); | 4455 m_objs_array.RemoveAll(); |
4407 m_bPageLoadedOK = TRUE; | 4456 m_bPageLoadedOK = TRUE; |
4408 } else { | 4457 } else { |
4409 return bRet; | 4458 return bRet; |
4410 } | 4459 } |
4411 } else { | 4460 } else { |
4412 CFX_PtrArray new_objs_array; | 4461 CFX_PtrArray new_objs_array; |
4413 FX_BOOL bRet = | 4462 FX_BOOL bRet = |
4414 IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); | 4463 IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); |
4415 m_objs_array.RemoveAll(); | 4464 m_objs_array.RemoveAll(); |
4416 if (bRet) { | 4465 if (bRet) { |
4417 m_bPageLoadedOK = TRUE; | 4466 m_bPageLoadedOK = TRUE; |
4418 } else { | 4467 } else { |
4419 m_objs_array.Append(new_objs_array); | 4468 m_objs_array.Append(new_objs_array); |
4420 return bRet; | 4469 return PDF_DATA_NOTAVAIL; |
4421 } | 4470 } |
4422 } | 4471 } |
4423 } | 4472 } |
4424 if (m_bPageLoadedOK) { | 4473 if (m_bPageLoadedOK) { |
4425 if (!m_bAnnotsLoad) { | 4474 if (!m_bAnnotsLoad) { |
4426 if (!CheckPageAnnots(iPage, pHints)) { | 4475 if (!CheckPageAnnots(iPage, pHints)) { |
4427 return FALSE; | 4476 return PDF_DATA_NOTAVAIL; |
4428 } | 4477 } |
4429 m_bAnnotsLoad = TRUE; | 4478 m_bAnnotsLoad = TRUE; |
4430 } | 4479 } |
4431 } | 4480 } |
4432 if (m_pPageDict && !m_bNeedDownLoadResource) { | 4481 if (m_pPageDict && !m_bNeedDownLoadResource) { |
4433 m_pPageResource = m_pPageDict->GetElement("Resources"); | 4482 m_pPageResource = m_pPageDict->GetElement("Resources"); |
4434 if (!m_pPageResource) { | 4483 if (!m_pPageResource) { |
4435 m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict); | 4484 m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict); |
4436 } else { | 4485 } else { |
4437 m_bNeedDownLoadResource = TRUE; | 4486 m_bNeedDownLoadResource = TRUE; |
4438 } | 4487 } |
4439 } | 4488 } |
4440 if (m_bNeedDownLoadResource) { | 4489 if (m_bNeedDownLoadResource) { |
4441 FX_BOOL bRet = CheckResources(pHints); | 4490 FX_BOOL bRet = CheckResources(pHints); |
4442 if (!bRet) { | 4491 if (!bRet) { |
4443 return FALSE; | 4492 return PDF_DATA_NOTAVAIL; |
4444 } | 4493 } |
4445 m_bNeedDownLoadResource = FALSE; | 4494 m_bNeedDownLoadResource = FALSE; |
4446 } | 4495 } |
4447 m_bPageLoadedOK = FALSE; | 4496 m_bPageLoadedOK = FALSE; |
4448 m_bAnnotsLoad = FALSE; | 4497 m_bAnnotsLoad = FALSE; |
4449 m_bCurPageDictLoadOK = FALSE; | 4498 m_bCurPageDictLoadOK = FALSE; |
4450 ResetFirstCheck(iPage); | 4499 ResetFirstCheck(iPage); |
4451 m_pagesLoadState.insert(iPage); | 4500 m_pagesLoadState.insert(iPage); |
4452 return TRUE; | 4501 return PDF_DATA_AVAIL; |
4453 } | 4502 } |
4454 FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) { | 4503 FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) { |
4455 if (!m_objs_array.GetSize()) { | 4504 if (!m_objs_array.GetSize()) { |
4456 m_objs_array.RemoveAll(); | 4505 m_objs_array.RemoveAll(); |
4457 CFX_PtrArray obj_array; | 4506 CFX_PtrArray obj_array; |
4458 obj_array.Add(m_pPageResource); | 4507 obj_array.Add(m_pPageResource); |
4459 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); | 4508 FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); |
4460 if (bRet) { | 4509 if (bRet) { |
4461 m_objs_array.RemoveAll(); | 4510 m_objs_array.RemoveAll(); |
4462 } | 4511 } |
4463 return bRet; | 4512 return bRet; |
4464 } | 4513 } |
4465 CFX_PtrArray new_objs_array; | 4514 CFX_PtrArray new_objs_array; |
4466 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); | 4515 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); |
4467 m_objs_array.RemoveAll(); | 4516 m_objs_array.RemoveAll(); |
4468 if (!bRet) { | 4517 if (!bRet) { |
4469 m_objs_array.Append(new_objs_array); | 4518 m_objs_array.Append(new_objs_array); |
4470 } | 4519 } |
4471 return bRet; | 4520 return bRet; |
4472 } | 4521 } |
4473 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, | 4522 void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, |
4474 FX_DWORD* pSize) { | 4523 FX_DWORD* pSize) { |
4475 if (pPos) { | 4524 if (pPos) { |
4476 *pPos = m_dwLastXRefOffset; | 4525 *pPos = m_dwLastXRefOffset; |
4477 } | 4526 } |
4478 if (pSize) { | 4527 if (pSize) { |
4479 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); | 4528 *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); |
4480 } | 4529 } |
4481 } | 4530 } |
4531 int CPDF_DataAvail::GetPageCount() const { | |
4532 if (m_pLinearized) { | |
4533 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); | |
4534 CPDF_Object* pObj = pDict ? pDict->GetElementValue(FX_BSTRC("N")) : nullptr; | |
4535 return pObj ? pObj->GetInteger() : 0; | |
4536 } | |
4537 return m_pDocument ? m_pDocument->GetPageCount() : 0; | |
4538 } | |
4539 CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) { | |
4540 if (!m_pDocument || index < 0 || index >= this->GetPageCount()) { | |
4541 return nullptr; | |
4542 } | |
4543 if (m_pLinearized) { | |
4544 CPDF_Dictionary* pDict = m_pLinearized->GetDict(); | |
4545 CPDF_Object* pObj = pDict ? pDict->GetElementValue(FX_BSTRC("P")) : nullptr; | |
4546 int pageNum = pObj ? pObj->GetInteger() : 0; | |
4547 if (m_pHintTables && index != pageNum) { | |
4548 FX_FILESIZE szPageStartPos = 0; | |
4549 FX_FILESIZE szPageLength = 0; | |
4550 FX_DWORD dwObjNum = 0; | |
4551 FX_BOOL bPagePosGot = m_pHintTables->GetPagePos(index, szPageStartPos, | |
4552 szPageLength, dwObjNum); | |
4553 if (!bPagePosGot) { | |
4554 return nullptr; | |
4555 } | |
4556 m_syntaxParser.InitParser(m_pFileRead, (FX_DWORD)szPageStartPos); | |
4557 CPDF_Object* pPageDict = ParseIndirectObjectAt(0, dwObjNum, m_pDocument); | |
4558 if (!pPageDict) { | |
4559 return nullptr; | |
4560 } | |
4561 m_pDocument->InsertIndirectObject(dwObjNum, pPageDict); | |
4562 return pPageDict->GetDict(); | |
4563 } | |
4564 } | |
4565 return m_pDocument->GetPage(index); | |
4566 } | |
4482 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) { | 4567 int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) { |
4483 if (!m_pDocument) { | 4568 if (!m_pDocument) { |
4484 return PDFFORM_AVAIL; | 4569 return PDF_FORM_AVAIL; |
4485 } | 4570 } |
4486 if (!m_bLinearizedFormParamLoad) { | 4571 if (!m_bLinearizedFormParamLoad) { |
4487 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); | 4572 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); |
4488 if (!pRoot) { | 4573 if (!pRoot) { |
4489 return PDFFORM_AVAIL; | 4574 return PDF_FORM_AVAIL; |
4490 } | 4575 } |
4491 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); | 4576 CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); |
4492 if (!pAcroForm) { | 4577 if (!pAcroForm) { |
4493 return PDFFORM_NOTEXIST; | 4578 return PDF_FORM_NOTEXIST; |
4494 } | 4579 } |
4495 if (!CheckLinearizedData(pHints)) { | 4580 if (!CheckLinearizedData(pHints)) { |
4496 return PDFFORM_NOTAVAIL; | 4581 return PDF_FORM_NOTAVAIL; |
4497 } | 4582 } |
4498 if (!m_objs_array.GetSize()) { | 4583 if (!m_objs_array.GetSize()) { |
4499 m_objs_array.Add(pAcroForm->GetDict()); | 4584 m_objs_array.Add(pAcroForm->GetDict()); |
4500 } | 4585 } |
4501 m_bLinearizedFormParamLoad = TRUE; | 4586 m_bLinearizedFormParamLoad = TRUE; |
4502 } | 4587 } |
4503 CFX_PtrArray new_objs_array; | 4588 CFX_PtrArray new_objs_array; |
4504 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); | 4589 FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); |
4505 m_objs_array.RemoveAll(); | 4590 m_objs_array.RemoveAll(); |
4506 if (!bRet) { | 4591 if (!bRet) { |
4507 m_objs_array.Append(new_objs_array); | 4592 m_objs_array.Append(new_objs_array); |
4508 return PDFFORM_NOTAVAIL; | 4593 return PDF_FORM_NOTAVAIL; |
4509 } | 4594 } |
4510 return PDFFORM_AVAIL; | 4595 return PDF_FORM_AVAIL; |
4511 } | 4596 } |
4512 void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) { | 4597 void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) { |
4513 int32_t iNext = 0; | 4598 int32_t iNext = 0; |
4514 if (BinarySearch(dwObjNum, iNext)) { | 4599 if (BinarySearch(dwObjNum, iNext)) { |
4515 return; | 4600 return; |
4516 } | 4601 } |
4517 m_number_array.InsertAt(iNext, dwObjNum); | 4602 m_number_array.InsertAt(iNext, dwObjNum); |
4518 } | 4603 } |
4519 FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) { | 4604 FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) { |
4520 int32_t iNext = 0; | 4605 int32_t iNext = 0; |
(...skipping 18 matching lines...) Expand all Loading... | |
4539 return FALSE; | 4624 return FALSE; |
4540 } | 4625 } |
4541 CPDF_PageNode::~CPDF_PageNode() { | 4626 CPDF_PageNode::~CPDF_PageNode() { |
4542 int32_t iSize = m_childNode.GetSize(); | 4627 int32_t iSize = m_childNode.GetSize(); |
4543 for (int32_t i = 0; i < iSize; ++i) { | 4628 for (int32_t i = 0; i < iSize; ++i) { |
4544 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; | 4629 CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; |
4545 delete pNode; | 4630 delete pNode; |
4546 } | 4631 } |
4547 m_childNode.RemoveAll(); | 4632 m_childNode.RemoveAll(); |
4548 } | 4633 } |
4634 CPDF_HintTables::~CPDF_HintTables() { | |
4635 m_dwDeltaNObjsArray.RemoveAll(); | |
4636 m_dwNSharedObjsArray.RemoveAll(); | |
4637 m_dwSharedObjNumArray.RemoveAll(); | |
4638 m_dwIdentifierArray.RemoveAll(); | |
4639 m_szPageOffsetArray.RemoveAll(); | |
4640 m_szSharedObjOffsetArray.RemoveAll(); | |
4641 } | |
4642 FX_DWORD CPDF_HintTables::GetItemLength(int index, | |
4643 const CFX_FileSizeArray& szArray) { | |
4644 if (index < 0 || szArray.GetSize() < 2 || index > szArray.GetSize() - 2 || | |
4645 szArray[index] > szArray[index + 1]) | |
4646 return 0; | |
4647 return szArray[index + 1] - szArray[index]; | |
4648 } | |
4649 FX_BOOL CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) { | |
4650 if (!hStream) | |
4651 return FALSE; | |
4652 int nStreamOffset = ReadPrimaryHintStreamOffset(); | |
4653 int nStreamLen = ReadPrimaryHintStreamLength(); | |
4654 if (nStreamOffset < 0 || nStreamLen < 1) | |
4655 return FALSE; | |
4656 // Item 1: The least number of objects in a page. | |
4657 FX_DWORD dwObjLeastNum = hStream->GetBits(32); | |
4658 // Item 2: The location of the first page's page object. | |
4659 FX_DWORD dwFirstObjLoc = hStream->GetBits(32); | |
4660 if (dwFirstObjLoc > nStreamOffset) { | |
4661 FX_SAFE_DWORD safeLoc = pdfium::base::checked_cast<FX_DWORD>(nStreamLen); | |
4662 safeLoc += dwFirstObjLoc; | |
4663 if (!safeLoc.IsValid()) | |
4664 return FALSE; | |
4665 m_szFirstPageObjOffset = | |
4666 pdfium::base::checked_cast<FX_FILESIZE>(safeLoc.ValueOrDie()); | |
4667 } else { | |
4668 m_szFirstPageObjOffset = | |
4669 pdfium::base::checked_cast<FX_FILESIZE>(dwFirstObjLoc); | |
4670 } | |
4671 // Item 3: The number of bits needed to represent the difference | |
4672 // between the greatest and least number of objects in a page. | |
4673 FX_DWORD dwDeltaObjectsBits = hStream->GetBits(16); | |
4674 // Item 4: The least length of a page in bytes. | |
4675 FX_DWORD dwPageLeastLen = hStream->GetBits(32); | |
4676 // Item 5: The number of bits needed to represent the difference | |
4677 // between the greatest and least length of a page, in bytes. | |
4678 FX_DWORD dwDeltaPageLenBits = hStream->GetBits(16); | |
4679 // Skip Item 6, 7, 8, 9 total 96 bits. | |
4680 hStream->SkipBits(96); | |
4681 // Item 10: The number of bits needed to represent the greatest | |
4682 // number of shared object references. | |
4683 FX_DWORD dwSharedObjBits = hStream->GetBits(16); | |
4684 // Item 11: The number of bits needed to represent the numerically | |
4685 // greatest shared object identifier used by the pages. | |
4686 FX_DWORD dwSharedIdBits = hStream->GetBits(16); | |
4687 // Item 12: The number of bits needed to represent the numerator of | |
4688 // the fractional position for each shared object reference. For each | |
4689 // shared object referenced from a page, there is an indication of | |
4690 // where in the page's content stream the object is first referenced. | |
4691 FX_DWORD dwSharedNumeratorBits = hStream->GetBits(16); | |
4692 // Item 13: Skip Item 13 which has 16 bits. | |
4693 FX_DWORD dwSharedDenominator = hStream->GetBits(16); | |
4694 CPDF_Object* pPageNum = m_pLinearizedDict->GetElementValue(FX_BSTRC("N")); | |
4695 int nPages = pPageNum ? pPageNum->GetInteger() : 0; | |
4696 if (nPages < 1) | |
4697 return FALSE; | |
4698 for (int i = 0; i < nPages; ++i) { | |
4699 FX_SAFE_DWORD safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits); | |
4700 safeDeltaObj += dwObjLeastNum; | |
4701 if (!safeDeltaObj.IsValid()) | |
4702 return FALSE; | |
4703 m_dwDeltaNObjsArray.Add(safeDeltaObj.ValueOrDie()); | |
4704 } | |
4705 hStream->ByteAlign(); | |
4706 CFX_DWordArray dwPageLenArray; | |
4707 for (int i = 0; i < nPages; ++i) { | |
4708 FX_SAFE_DWORD safePageLen = hStream->GetBits(dwDeltaPageLenBits); | |
4709 safePageLen += dwPageLeastLen; | |
4710 if (!safePageLen.IsValid()) | |
4711 return FALSE; | |
4712 dwPageLenArray.Add(safePageLen.ValueOrDie()); | |
4713 } | |
4714 CPDF_Object* pOffsetE = m_pLinearizedDict->GetElementValue(FX_BSTRC("E")); | |
4715 int nOffsetE = pOffsetE ? pOffsetE->GetInteger() : -1; | |
4716 if (nOffsetE < 0) | |
4717 return FALSE; | |
4718 CPDF_Object* pFirstPageNum = | |
4719 m_pLinearizedDict->GetElementValue(FX_BSTRC("P")); | |
4720 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; | |
4721 for (int i = 0; i < nPages; ++i) { | |
4722 if (i == nFirstPageNum) { | |
4723 m_szPageOffsetArray.Add(m_szFirstPageObjOffset); | |
4724 } else if (i == nFirstPageNum + 1) { | |
4725 if (i == 1) { | |
4726 m_szPageOffsetArray.Add(nOffsetE); | |
4727 } else { | |
4728 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 2] + | |
4729 dwPageLenArray[i - 2]); | |
4730 } | |
4731 } else { | |
4732 if (i == 0) { | |
4733 m_szPageOffsetArray.Add(nOffsetE); | |
4734 } else { | |
4735 m_szPageOffsetArray.Add(m_szPageOffsetArray[i - 1] + | |
4736 dwPageLenArray[i - 1]); | |
4737 } | |
4738 } | |
4739 } | |
4740 if (nPages > 0) { | |
4741 m_szPageOffsetArray.Add(m_szPageOffsetArray[nPages - 1] + | |
4742 dwPageLenArray[nPages - 1]); | |
4743 } | |
4744 hStream->ByteAlign(); | |
4745 // number of shared objects | |
4746 for (int i = 0; i < nPages; i++) { | |
4747 m_dwNSharedObjsArray.Add(hStream->GetBits(dwSharedObjBits)); | |
4748 } | |
4749 hStream->ByteAlign(); | |
4750 // array of identifier, sizes = nshared_objects | |
4751 for (int i = 0; i < nPages; i++) { | |
4752 for (int j = 0; j < m_dwNSharedObjsArray[i]; j++) { | |
4753 m_dwIdentifierArray.Add(hStream->GetBits(dwSharedIdBits)); | |
4754 } | |
4755 } | |
4756 hStream->ByteAlign(); | |
4757 for (int i = 0; i < nPages; i++) { | |
4758 FX_SAFE_DWORD safeSize = m_dwNSharedObjsArray[i]; | |
4759 safeSize *= dwSharedNumeratorBits; | |
4760 if (!safeSize.IsValid()) | |
4761 return FALSE; | |
4762 hStream->SkipBits(safeSize.ValueOrDie()); | |
4763 } | |
4764 hStream->ByteAlign(); | |
4765 FX_SAFE_DWORD safeTotalPageLen = pdfium::base::checked_cast<FX_DWORD>(nPages); | |
4766 safeTotalPageLen *= dwDeltaPageLenBits; | |
4767 if (!safeTotalPageLen.IsValid()) | |
4768 return FALSE; | |
4769 hStream->SkipBits(safeTotalPageLen.ValueOrDie()); | |
4770 hStream->ByteAlign(); | |
4771 return TRUE; | |
4772 } | |
4773 FX_BOOL CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream) { | |
4774 if (!hStream) | |
4775 return FALSE; | |
4776 int nStreamOffset = ReadPrimaryHintStreamOffset(); | |
4777 int nStreamLen = ReadPrimaryHintStreamLength(); | |
4778 if (nStreamOffset < 0 || nStreamLen < 1) | |
4779 return FALSE; | |
4780 // Item 1: The object number of the first object in the shared objects | |
4781 // section. | |
4782 FX_DWORD dwFirstSharedObjNum = hStream->GetBits(32); | |
4783 // Item 2: The location of the first object in the shared objects section. | |
4784 FX_DWORD dwFirstSharedObjLoc = hStream->GetBits(32); | |
4785 if (dwFirstSharedObjLoc > nStreamOffset) | |
4786 dwFirstSharedObjLoc += nStreamLen; | |
4787 // Item 3: The number of shared object entries for the first page. | |
4788 m_nFirstPageSharedObjs = hStream->GetBits(32); | |
4789 // Item 4: The number of shared object entries for the shared objects | |
4790 // section, including the number of shared object entries for the first page. | |
4791 FX_DWORD dwSharedObjTotal = hStream->GetBits(32); | |
4792 // Item 5: The number of bits needed to represent the greatest number of | |
4793 // objects in a shared object group. Skipped. | |
4794 hStream->SkipBits(16); | |
4795 // Item 6: The least length of a shared object group in bytes. | |
4796 FX_DWORD dwGroupLeastLen = hStream->GetBits(32); | |
4797 // Item 7: The number of bits needed to represent the difference between the | |
4798 // greatest and least length of a shared object group, in bytes. | |
4799 FX_DWORD dwDeltaGroupLen = hStream->GetBits(16); | |
4800 CPDF_Object* pFirstPageObj = | |
4801 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); | |
4802 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; | |
4803 if (nFirstPageObjNum < 0) | |
4804 return FALSE; | |
4805 FX_DWORD dwPrevObjLen = 0; | |
4806 FX_DWORD dwCurObjLen = 0; | |
4807 for (int i = 0; i < dwSharedObjTotal; ++i) { | |
4808 dwPrevObjLen = dwCurObjLen; | |
4809 FX_SAFE_DWORD safeObjLen = hStream->GetBits(dwDeltaGroupLen); | |
4810 safeObjLen += dwGroupLeastLen; | |
4811 if (!safeObjLen.IsValid()) | |
4812 return FALSE; | |
4813 dwCurObjLen = safeObjLen.ValueOrDie(); | |
4814 if (i < m_nFirstPageSharedObjs) { | |
4815 m_dwSharedObjNumArray.Add(nFirstPageObjNum + i); | |
4816 if (i == 0) | |
4817 m_szSharedObjOffsetArray.Add(m_szFirstPageObjOffset); | |
4818 } else { | |
4819 FX_SAFE_DWORD safeObjNum = dwFirstSharedObjNum; | |
4820 safeObjNum += i - m_nFirstPageSharedObjs; | |
4821 if (!safeObjNum.IsValid()) | |
4822 return FALSE; | |
4823 m_dwSharedObjNumArray.Add(safeObjNum.ValueOrDie()); | |
4824 if (i == m_nFirstPageSharedObjs) | |
4825 m_szSharedObjOffsetArray.Add( | |
4826 pdfium::base::checked_cast<int32_t>(dwFirstSharedObjLoc)); | |
4827 } | |
4828 if (i != 0 && i != m_nFirstPageSharedObjs) { | |
4829 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwPrevObjLen); | |
4830 safeLoc += m_szSharedObjOffsetArray[i - 1]; | |
4831 if (!safeLoc.IsValid()) | |
4832 return FALSE; | |
4833 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie()); | |
4834 } | |
4835 } | |
4836 if (dwSharedObjTotal > 0) { | |
4837 FX_SAFE_INT32 safeLoc = pdfium::base::checked_cast<int32_t>(dwCurObjLen); | |
4838 safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1]; | |
4839 if (!safeLoc.IsValid()) | |
4840 return FALSE; | |
4841 m_szSharedObjOffsetArray.Add(safeLoc.ValueOrDie()); | |
4842 } | |
4843 hStream->ByteAlign(); | |
4844 hStream->SkipBits(dwSharedObjTotal); | |
4845 hStream->ByteAlign(); | |
4846 return TRUE; | |
4847 } | |
4848 FX_BOOL CPDF_HintTables::GetPagePos(int index, | |
4849 FX_FILESIZE& szPageStartPos, | |
4850 FX_FILESIZE& szPageLength, | |
4851 FX_DWORD& dwObjNum) { | |
4852 if (!m_pLinearizedDict) | |
4853 return FALSE; | |
4854 szPageStartPos = m_szPageOffsetArray[index]; | |
4855 szPageLength = GetItemLength(index, m_szPageOffsetArray); | |
4856 CPDF_Object* pFirstPageNum = | |
4857 m_pLinearizedDict->GetElementValue(FX_BSTRC("P")); | |
4858 int nFirstPageNum = pFirstPageNum ? pFirstPageNum->GetInteger() : 0; | |
4859 CPDF_Object* pFirstPageObjNum = | |
4860 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); | |
4861 if (!pFirstPageObjNum) | |
4862 return FALSE; | |
4863 int nFirstPageObjNum = pFirstPageObjNum->GetInteger(); | |
4864 if (index == nFirstPageNum) { | |
4865 dwObjNum = nFirstPageObjNum; | |
4866 return TRUE; | |
4867 } | |
4868 // The object number of remaining pages starts from 1. | |
4869 dwObjNum = 1; | |
4870 for (int i = 0; i < index; ++i) { | |
4871 if (i == nFirstPageNum) | |
4872 continue; | |
4873 dwObjNum += m_dwDeltaNObjsArray[i]; | |
4874 } | |
4875 return TRUE; | |
4876 } | |
4877 int32_t CPDF_HintTables::CheckPage(int index, IFX_DownloadHints* pHints) { | |
4878 if (!m_pLinearizedDict || !pHints) | |
4879 return PDF_DATA_ERROR; | |
4880 CPDF_Object* pFirstAvailPage = | |
4881 m_pLinearizedDict->GetElementValue(FX_BSTRC("P")); | |
4882 int nFirstAvailPage = pFirstAvailPage ? pFirstAvailPage->GetInteger() : 0; | |
4883 if (index == nFirstAvailPage) | |
4884 return PDF_DATA_AVAIL; | |
4885 FX_DWORD dwLength = GetItemLength(index, m_szPageOffsetArray); | |
4886 if (!dwLength || | |
4887 !m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength, | |
4888 pHints)) { | |
4889 return PDF_DATA_NOTAVAIL; | |
4890 } | |
4891 // Download data of shared objects in the page. | |
4892 FX_DWORD offset = 0; | |
4893 for (int i = 0; i < index; ++i) { | |
4894 offset += m_dwNSharedObjsArray[i]; | |
4895 } | |
4896 CPDF_Object* pFirstPageObj = | |
4897 m_pLinearizedDict->GetElementValue(FX_BSTRC("O")); | |
4898 int nFirstPageObjNum = pFirstPageObj ? pFirstPageObj->GetInteger() : -1; | |
4899 if (nFirstPageObjNum < 0) | |
4900 return FALSE; | |
4901 FX_DWORD dwIndex = 0; | |
4902 FX_DWORD dwObjNum = 0; | |
4903 for (int j = 0; j < m_dwNSharedObjsArray[index]; ++j) { | |
4904 dwIndex = m_dwIdentifierArray[offset + j]; | |
4905 dwObjNum = m_dwSharedObjNumArray[dwIndex]; | |
4906 if (dwObjNum >= nFirstPageObjNum && | |
4907 dwObjNum < nFirstPageObjNum + m_nFirstPageSharedObjs) { | |
4908 continue; | |
4909 } | |
4910 dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray); | |
4911 if (!dwLength || | |
4912 !m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength, | |
4913 pHints)) { | |
4914 return PDF_DATA_NOTAVAIL; | |
4915 } | |
4916 } | |
4917 return PDF_DATA_AVAIL; | |
4918 } | |
4919 FX_BOOL CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) { | |
4920 if (!pHintStream || !m_pLinearizedDict) | |
4921 return FALSE; | |
4922 CPDF_Dictionary* pDict = pHintStream->GetDict(); | |
4923 CPDF_Object* pOffset = pDict ? pDict->GetElement(FX_BSTRC("S")) : nullptr; | |
4924 if (!pOffset || pOffset->GetType() != PDFOBJ_NUMBER) | |
4925 return FALSE; | |
4926 CPDF_StreamAcc acc; | |
4927 acc.LoadAllData(pHintStream); | |
4928 FX_DWORD size = acc.GetSize(); | |
4929 // The header section of page offset hint table is 36 bytes. | |
4930 // The header section of shared object hint table is 24 bytes. | |
4931 // Hint table has at least 60 bytes. | |
4932 const FX_DWORD MIN_STREAM_LEN = 60; | |
4933 if (size < MIN_STREAM_LEN || size < pOffset->GetInteger() || | |
4934 !pOffset->GetInteger()) { | |
4935 return FALSE; | |
4936 } | |
4937 CFX_BitStream bs; | |
4938 bs.Init(acc.GetData(), size); | |
4939 return ReadPageHintTable(&bs) && ReadSharedObjHintTable(&bs); | |
4940 } | |
4941 int CPDF_HintTables::ReadPrimaryHintStreamOffset() const { | |
4942 if (!m_pLinearizedDict) | |
4943 return -1; | |
4944 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); | |
4945 if (!pRange) | |
4946 return -1; | |
4947 CPDF_Object* pStreamOffset = pRange->GetElementValue(0); | |
4948 if (!pStreamOffset) | |
4949 return -1; | |
4950 return pStreamOffset->GetInteger(); | |
4951 } | |
4952 int CPDF_HintTables::ReadPrimaryHintStreamLength() const { | |
4953 if (!m_pLinearizedDict) | |
4954 return -1; | |
4955 CPDF_Array* pRange = m_pLinearizedDict->GetArray(FX_BSTRC("H")); | |
4956 if (!pRange) | |
4957 return -1; | |
4958 CPDF_Object* pStreamLen = pRange->GetElementValue(1); | |
4959 if (!pStreamLen) | |
4960 return -1; | |
4961 return pStreamLen->GetInteger(); | |
4962 } | |
OLD | NEW |