blob: a3accba7662a82fec9ddbd2ac09c32367a9e9ccc [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhangb4e7f302015-11-06 15:52:32 -08007#include "public/fpdf_dataavail.h"
8
thestigd4c34f22016-09-28 17:04:51 -07009#include <memory>
10#include <utility>
11
dsinclair488b7ad2016-10-04 11:55:50 -070012#include "core/fpdfapi/parser/cpdf_data_avail.h"
13#include "core/fpdfapi/parser/cpdf_document.h"
dsinclair114e46a2016-09-29 17:18:21 -070014#include "fpdfsdk/fsdk_define.h"
Lei Zhangb4e7f302015-11-06 15:52:32 -080015#include "public/fpdf_formfill.h"
tsepez36eb4bd2016-10-03 15:24:27 -070016#include "third_party/base/ptr_util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070017
Tom Sepezc7e4c4f2015-11-20 09:45:24 -080018// These checks are here because core/ and public/ cannot depend on each other.
thestig979070b2016-06-14 10:44:01 -070019static_assert(CPDF_DataAvail::DataError == PDF_DATA_ERROR,
20 "CPDF_DataAvail::DataError value mismatch");
21static_assert(CPDF_DataAvail::DataNotAvailable == PDF_DATA_NOTAVAIL,
22 "CPDF_DataAvail::DataNotAvailable value mismatch");
23static_assert(CPDF_DataAvail::DataAvailable == PDF_DATA_AVAIL,
24 "CPDF_DataAvail::DataAvailable value mismatch");
Tom Sepezc7e4c4f2015-11-20 09:45:24 -080025
thestig979070b2016-06-14 10:44:01 -070026static_assert(CPDF_DataAvail::LinearizationUnknown == PDF_LINEARIZATION_UNKNOWN,
27 "CPDF_DataAvail::LinearizationUnknown value mismatch");
28static_assert(CPDF_DataAvail::NotLinearized == PDF_NOT_LINEARIZED,
29 "CPDF_DataAvail::NotLinearized value mismatch");
30static_assert(CPDF_DataAvail::Linearized == PDF_LINEARIZED,
31 "CPDF_DataAvail::Linearized value mismatch");
Tom Sepezc7e4c4f2015-11-20 09:45:24 -080032
thestig979070b2016-06-14 10:44:01 -070033static_assert(CPDF_DataAvail::FormError == PDF_FORM_ERROR,
34 "CPDF_DataAvail::FormError value mismatch");
35static_assert(CPDF_DataAvail::FormNotAvailable == PDF_FORM_NOTAVAIL,
36 "CPDF_DataAvail::FormNotAvailable value mismatch");
37static_assert(CPDF_DataAvail::FormAvailable == PDF_FORM_AVAIL,
38 "CPDF_DataAvail::FormAvailable value mismatch");
39static_assert(CPDF_DataAvail::FormNotExist == PDF_FORM_NOTEXIST,
40 "CPDF_DataAvail::FormNotExist value mismatch");
Tom Sepezc7e4c4f2015-11-20 09:45:24 -080041
thestig979070b2016-06-14 10:44:01 -070042namespace {
43
44class CFPDF_FileAvailWrap : public CPDF_DataAvail::FileAvail {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070045 public:
thestig1cd352e2016-06-07 17:53:06 -070046 CFPDF_FileAvailWrap() { m_pfileAvail = nullptr; }
Lei Zhang2b1a2d52015-08-14 22:16:22 -070047 ~CFPDF_FileAvailWrap() override {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049 void Set(FX_FILEAVAIL* pfileAvail) { m_pfileAvail = pfileAvail; }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070050
thestig979070b2016-06-14 10:44:01 -070051 // CPDF_DataAvail::FileAvail:
tsepez4cf55152016-11-02 14:37:54 -070052 bool IsDataAvail(FX_FILESIZE offset, uint32_t size) override {
tsepez95e58342016-10-28 11:34:42 -070053 return !!m_pfileAvail->IsDataAvail(m_pfileAvail, offset, size);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070054 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070055
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056 private:
57 FX_FILEAVAIL* m_pfileAvail;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070058};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070059
tsepezad2441e2016-10-24 10:19:11 -070060class CFPDF_FileAccessWrap : public IFX_SeekableReadStream {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070061 public:
thestig1cd352e2016-06-07 17:53:06 -070062 CFPDF_FileAccessWrap() { m_pFileAccess = nullptr; }
Lei Zhang2b1a2d52015-08-14 22:16:22 -070063 ~CFPDF_FileAccessWrap() override {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064
Nico Weber9d8ec5a2015-08-04 13:00:21 -070065 void Set(FPDF_FILEACCESS* pFile) { m_pFileAccess = pFile; }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070066
tsepezad2441e2016-10-24 10:19:11 -070067 // IFX_SeekableReadStream
Lei Zhang2b1a2d52015-08-14 22:16:22 -070068 FX_FILESIZE GetSize() override { return m_pFileAccess->m_FileLen; }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070069
tsepezf39074c2016-10-26 15:33:58 -070070 bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
71 return !!m_pFileAccess->m_GetBlock(m_pFileAccess->m_Param, offset,
72 (uint8_t*)buffer, size);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070073 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070074
Lei Zhang2b1a2d52015-08-14 22:16:22 -070075 void Release() override {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070076
Nico Weber9d8ec5a2015-08-04 13:00:21 -070077 private:
78 FPDF_FILEACCESS* m_pFileAccess;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070079};
80
thestig979070b2016-06-14 10:44:01 -070081class CFPDF_DownloadHintsWrap : public CPDF_DataAvail::DownloadHints {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082 public:
Lei Zhang2b1a2d52015-08-14 22:16:22 -070083 explicit CFPDF_DownloadHintsWrap(FX_DOWNLOADHINTS* pDownloadHints) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070084 m_pDownloadHints = pDownloadHints;
85 }
Lei Zhang2b1a2d52015-08-14 22:16:22 -070086 ~CFPDF_DownloadHintsWrap() override {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070087
88 public:
Lei Zhang2b1a2d52015-08-14 22:16:22 -070089 // IFX_DownloadHints
tsepezc3255f52016-03-25 14:52:27 -070090 void AddSegment(FX_FILESIZE offset, uint32_t size) override {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070091 m_pDownloadHints->AddSegment(m_pDownloadHints, offset, size);
92 }
93
94 private:
95 FX_DOWNLOADHINTS* m_pDownloadHints;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070096};
97
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098class CFPDF_DataAvail {
99 public:
thestig979070b2016-06-14 10:44:01 -0700100 CFPDF_DataAvail() {}
101 ~CFPDF_DataAvail() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700102
thestig979070b2016-06-14 10:44:01 -0700103 std::unique_ptr<CPDF_DataAvail> m_pDataAvail;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104 CFPDF_FileAvailWrap m_FileAvail;
105 CFPDF_FileAccessWrap m_FileRead;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700106};
107
thestig979070b2016-06-14 10:44:01 -0700108CFPDF_DataAvail* CFPDFDataAvailFromFPDFAvail(FPDF_AVAIL avail) {
109 return static_cast<CFPDF_DataAvail*>(avail);
110}
111
112} // namespace
113
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700114DLLEXPORT FPDF_AVAIL STDCALL FPDFAvail_Create(FX_FILEAVAIL* file_avail,
115 FPDF_FILEACCESS* file) {
Tom Sepezae51c812015-08-05 12:34:06 -0700116 CFPDF_DataAvail* pAvail = new CFPDF_DataAvail;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700117 pAvail->m_FileAvail.Set(file_avail);
118 pAvail->m_FileRead.Set(file);
tsepez36eb4bd2016-10-03 15:24:27 -0700119 pAvail->m_pDataAvail = pdfium::MakeUnique<CPDF_DataAvail>(
tsepez95e58342016-10-28 11:34:42 -0700120 &pAvail->m_FileAvail, &pAvail->m_FileRead, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121 return pAvail;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700122}
123
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700124DLLEXPORT void STDCALL FPDFAvail_Destroy(FPDF_AVAIL avail) {
125 delete (CFPDF_DataAvail*)avail;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700126}
127
Dan Sinclairf766ad22016-03-14 13:51:24 -0400128DLLEXPORT int STDCALL FPDFAvail_IsDocAvail(FPDF_AVAIL avail,
129 FX_DOWNLOADHINTS* hints) {
Jun Fangdf7f3662015-11-10 18:29:18 +0800130 if (!avail || !hints)
131 return PDF_DATA_ERROR;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 CFPDF_DownloadHintsWrap hints_wrap(hints);
thestig979070b2016-06-14 10:44:01 -0700133 return CFPDFDataAvailFromFPDFAvail(avail)->m_pDataAvail->IsDocAvail(
134 &hints_wrap);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700135}
136
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137DLLEXPORT FPDF_DOCUMENT STDCALL
138FPDFAvail_GetDocument(FPDF_AVAIL avail, FPDF_BYTESTRING password) {
Tom Sepezf10ae632016-01-26 14:19:52 -0800139 CFPDF_DataAvail* pDataAvail = static_cast<CFPDF_DataAvail*>(avail);
140 if (!pDataAvail)
Lei Zhangaa23e702016-01-29 18:03:40 -0800141 return nullptr;
Tom Sepezf10ae632016-01-26 14:19:52 -0800142
tsepez4540fba2016-08-16 11:12:21 -0700143 std::unique_ptr<CPDF_Parser> pParser(new CPDF_Parser);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 pParser->SetPassword(password);
tsepez4540fba2016-08-16 11:12:21 -0700145
dsinclaircedaa552016-08-24 11:12:19 -0700146 std::unique_ptr<CPDF_Document> pDocument(
147 new CPDF_Document(std::move(pParser)));
148 CPDF_Parser::Error error = pDocument->GetParser()->StartLinearizedParse(
149 pDataAvail->m_pDataAvail->GetFileRead(), pDocument.get());
Tom Sepezf10ae632016-01-26 14:19:52 -0800150 if (error != CPDF_Parser::SUCCESS) {
Tom Sepezf10ae632016-01-26 14:19:52 -0800151 ProcessParseError(error);
Lei Zhangaa23e702016-01-29 18:03:40 -0800152 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 }
dsinclaircedaa552016-08-24 11:12:19 -0700154 pDataAvail->m_pDataAvail->SetDocument(pDocument.get());
155 CheckUnSupportError(pDocument.get(), FPDF_ERR_SUCCESS);
156 return FPDFDocumentFromCPDFDocument(pDocument.release());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700157}
158
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159DLLEXPORT int STDCALL FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc) {
Tom Sepez471a1032015-10-15 16:17:18 -0700160 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
161 return pDoc ? pDoc->GetParser()->GetFirstPageNo() : 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700162}
163
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700164DLLEXPORT int STDCALL FPDFAvail_IsPageAvail(FPDF_AVAIL avail,
165 int page_index,
166 FX_DOWNLOADHINTS* hints) {
Jun Fangdf7f3662015-11-10 18:29:18 +0800167 if (!avail || !hints)
168 return PDF_DATA_ERROR;
thestige0cb6872016-09-01 13:41:10 -0700169 if (page_index < 0)
170 return PDF_DATA_NOTAVAIL;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 CFPDF_DownloadHintsWrap hints_wrap(hints);
thestig979070b2016-06-14 10:44:01 -0700172 return CFPDFDataAvailFromFPDFAvail(avail)->m_pDataAvail->IsPageAvail(
173 page_index, &hints_wrap);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700174}
175
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176DLLEXPORT int STDCALL FPDFAvail_IsFormAvail(FPDF_AVAIL avail,
177 FX_DOWNLOADHINTS* hints) {
Jun Fangdf7f3662015-11-10 18:29:18 +0800178 if (!avail || !hints)
179 return PDF_FORM_ERROR;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180 CFPDF_DownloadHintsWrap hints_wrap(hints);
thestig979070b2016-06-14 10:44:01 -0700181 return CFPDFDataAvailFromFPDFAvail(avail)->m_pDataAvail->IsFormAvail(
182 &hints_wrap);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700183}
184
Jun Fangdf7f3662015-11-10 18:29:18 +0800185DLLEXPORT int STDCALL FPDFAvail_IsLinearized(FPDF_AVAIL avail) {
186 if (!avail)
187 return PDF_LINEARIZATION_UNKNOWN;
thestig979070b2016-06-14 10:44:01 -0700188 return CFPDFDataAvailFromFPDFAvail(avail)->m_pDataAvail->IsLinearizedPDF();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700189}