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

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

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

Powered by Google App Engine
This is Rietveld 408576698