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

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

Issue 1353093003: Support linearized loading (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 5 years, 1 month 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 "../../../../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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698