blob: 05e32ee63e7037dadecd3024e27a512805f6526e [file] [log] [blame]
Dan Sinclair7aba4722018-03-28 17:04:16 +00001// Copyright 2018 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.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Dan Sinclair00d47a62018-03-28 18:39:04 +00007#include "fpdfsdk/cpdfsdk_helpers.h"
Dan Sinclair7aba4722018-03-28 17:04:16 +00008
Lei Zhangbc106482019-05-30 23:55:19 +00009#include "build/build_config.h"
Lei Zhang865ffb12019-02-26 20:18:19 +000010#include "constants/form_fields.h"
Lei Zhang26170562018-04-17 17:01:52 +000011#include "constants/stream_dict_common.h"
Tom Sepeza1d34422018-04-24 20:54:41 +000012#include "core/fpdfapi/page/cpdf_page.h"
Dan Sinclair7aba4722018-03-28 17:04:16 +000013#include "core/fpdfapi/parser/cpdf_array.h"
Lei Zhang81535612018-10-09 21:15:17 +000014#include "core/fpdfapi/parser/cpdf_dictionary.h"
Dan Sinclair7aba4722018-03-28 17:04:16 +000015#include "core/fpdfapi/parser/cpdf_document.h"
Artem Strygineababa12018-06-06 12:31:18 +000016#include "core/fpdfapi/parser/cpdf_stream_acc.h"
Gourab Kundud35a62d2020-04-24 10:29:27 +000017#include "core/fpdfapi/render/cpdf_renderoptions.h"
Dan Sinclair7aba4722018-03-28 17:04:16 +000018#include "core/fpdfdoc/cpdf_annot.h"
Lei Zhangc3450652018-10-11 16:54:42 +000019#include "core/fpdfdoc/cpdf_interactiveform.h"
Dan Sinclair7aba4722018-03-28 17:04:16 +000020#include "core/fpdfdoc/cpdf_metadata.h"
Tom Sepez5bfc5f52021-03-31 20:26:42 +000021#include "core/fxcrt/unowned_ptr.h"
Lei Zhange6fcdfa2019-02-14 04:07:09 +000022#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
Tom Sepez9c78c0d2021-01-27 20:13:14 +000023#include "third_party/base/check.h"
Tom Sepezc524b1f2021-04-06 00:09:39 +000024#include "third_party/base/numerics/safe_conversions.h"
Dan Sinclair7aba4722018-03-28 17:04:16 +000025
26namespace {
27
Ralf Sippl16381792018-04-12 21:20:26 +000028constexpr char kQuadPoints[] = "QuadPoints";
29
Lei Zhang65a8d5e2018-12-20 19:13:21 +000030// 0 bit: FPDF_POLICY_MACHINETIME_ACCESS
Lei Zhangbc106482019-05-30 23:55:19 +000031uint32_t g_sandbox_policy = 0xFFFFFFFF;
Lei Zhang65a8d5e2018-12-20 19:13:21 +000032
Tom Sepez20c946f2019-07-31 19:33:21 +000033UNSUPPORT_INFO* g_unsupport_info = nullptr;
34
Lei Zhangb7d09ca2019-02-27 23:50:44 +000035bool RaiseUnsupportedError(int nError) {
Tom Sepez20c946f2019-07-31 19:33:21 +000036 if (!g_unsupport_info)
Dan Sinclair7aba4722018-03-28 17:04:16 +000037 return false;
38
Tom Sepez20c946f2019-07-31 19:33:21 +000039 if (g_unsupport_info->FSDK_UnSupport_Handler)
40 g_unsupport_info->FSDK_UnSupport_Handler(g_unsupport_info, nError);
Dan Sinclair7aba4722018-03-28 17:04:16 +000041 return true;
42}
43
Lei Zhang85e09df2020-02-27 14:48:07 +000044// Use the existence of the XFA array as a signal for XFA forms.
45bool DocHasXFA(const CPDF_Document* doc) {
46 const CPDF_Dictionary* root = doc->GetRoot();
47 if (!root)
48 return false;
49
50 const CPDF_Dictionary* form = root->GetDictFor("AcroForm");
51 return form && form->GetArrayFor("XFA");
52}
53
Jeremy Chinsen617a2e82019-06-20 00:11:12 +000054unsigned long GetStreamMaybeCopyAndReturnLengthImpl(const CPDF_Stream* stream,
55 void* buffer,
56 unsigned long buflen,
57 bool decode) {
Tom Sepez9c78c0d2021-01-27 20:13:14 +000058 DCHECK(stream);
Jeremy Chinsen617a2e82019-06-20 00:11:12 +000059 auto stream_acc = pdfium::MakeRetain<CPDF_StreamAcc>(stream);
60
61 if (decode)
62 stream_acc->LoadAllDataFiltered();
63 else
64 stream_acc->LoadAllDataRaw();
65
66 const auto stream_data_size = stream_acc->GetSize();
67 if (!buffer || buflen < stream_data_size)
68 return stream_data_size;
69
70 memcpy(buffer, stream_acc->GetData(), stream_data_size);
71 return stream_data_size;
72}
73
Dan Sinclair7aba4722018-03-28 17:04:16 +000074#ifdef PDF_ENABLE_XFA
Tom Sepez55865452018-08-27 20:18:04 +000075class FPDF_FileHandlerContext final : public IFX_SeekableStream {
Dan Sinclair7aba4722018-03-28 17:04:16 +000076 public:
Tom Sepezb9d9b612020-06-17 20:47:22 +000077 CONSTRUCT_VIA_MAKE_RETAIN;
Dan Sinclair7aba4722018-03-28 17:04:16 +000078
Dan Sinclair7aba4722018-03-28 17:04:16 +000079 // IFX_SeekableStream:
80 FX_FILESIZE GetSize() override;
81 bool IsEOF() override;
82 FX_FILESIZE GetPosition() override;
Lei Zhangf6a79212018-11-15 20:17:49 +000083 bool ReadBlockAtOffset(void* buffer,
84 FX_FILESIZE offset,
85 size_t size) override;
Dan Sinclair7aba4722018-03-28 17:04:16 +000086 size_t ReadBlock(void* buffer, size_t size) override;
Lei Zhang59f76232018-11-15 20:22:59 +000087 bool WriteBlockAtOffset(const void* buffer,
88 FX_FILESIZE offset,
89 size_t size) override;
Dan Sinclair7aba4722018-03-28 17:04:16 +000090 bool Flush() override;
91
92 void SetPosition(FX_FILESIZE pos) { m_nCurPos = pos; }
93
Tom Sepezcb798252018-09-17 18:25:32 +000094 private:
Dan Sinclair7aba4722018-03-28 17:04:16 +000095 explicit FPDF_FileHandlerContext(FPDF_FILEHANDLER* pFS);
Lei Zhang86688de2018-05-22 22:06:49 +000096 ~FPDF_FileHandlerContext() override;
Dan Sinclair7aba4722018-03-28 17:04:16 +000097
Tom Sepez5bfc5f52021-03-31 20:26:42 +000098 UnownedPtr<FPDF_FILEHANDLER> const m_pFS;
99 FX_FILESIZE m_nCurPos = 0;
Dan Sinclair7aba4722018-03-28 17:04:16 +0000100};
101
Tom Sepez5bfc5f52021-03-31 20:26:42 +0000102FPDF_FileHandlerContext::FPDF_FileHandlerContext(FPDF_FILEHANDLER* pFS)
103 : m_pFS(pFS) {}
Dan Sinclair7aba4722018-03-28 17:04:16 +0000104
105FPDF_FileHandlerContext::~FPDF_FileHandlerContext() {
106 if (m_pFS && m_pFS->Release)
107 m_pFS->Release(m_pFS->clientData);
108}
109
110FX_FILESIZE FPDF_FileHandlerContext::GetSize() {
111 if (m_pFS && m_pFS->GetSize)
Tom Sepez5bfc5f52021-03-31 20:26:42 +0000112 return static_cast<FX_FILESIZE>(m_pFS->GetSize(m_pFS->clientData));
Dan Sinclair7aba4722018-03-28 17:04:16 +0000113 return 0;
114}
115
116bool FPDF_FileHandlerContext::IsEOF() {
117 return m_nCurPos >= GetSize();
118}
119
120FX_FILESIZE FPDF_FileHandlerContext::GetPosition() {
121 return m_nCurPos;
122}
123
Lei Zhangf6a79212018-11-15 20:17:49 +0000124bool FPDF_FileHandlerContext::ReadBlockAtOffset(void* buffer,
125 FX_FILESIZE offset,
126 size_t size) {
Dan Sinclair7aba4722018-03-28 17:04:16 +0000127 if (!buffer || !size || !m_pFS->ReadBlock)
128 return false;
129
130 if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
131 (FPDF_DWORD)size) == 0) {
132 m_nCurPos = offset + size;
133 return true;
134 }
135 return false;
136}
137
138size_t FPDF_FileHandlerContext::ReadBlock(void* buffer, size_t size) {
139 if (!buffer || !size || !m_pFS->ReadBlock)
140 return 0;
141
142 FX_FILESIZE nSize = GetSize();
143 if (m_nCurPos >= nSize)
144 return 0;
145 FX_FILESIZE dwAvail = nSize - m_nCurPos;
146 if (dwAvail < (FX_FILESIZE)size)
147 size = static_cast<size_t>(dwAvail);
148 if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)m_nCurPos, buffer,
149 (FPDF_DWORD)size) == 0) {
150 m_nCurPos += size;
151 return size;
152 }
153
154 return 0;
155}
156
Lei Zhang59f76232018-11-15 20:22:59 +0000157bool FPDF_FileHandlerContext::WriteBlockAtOffset(const void* buffer,
158 FX_FILESIZE offset,
159 size_t size) {
Dan Sinclair7aba4722018-03-28 17:04:16 +0000160 if (!m_pFS || !m_pFS->WriteBlock)
161 return false;
162
163 if (m_pFS->WriteBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
164 (FPDF_DWORD)size) == 0) {
165 m_nCurPos = offset + size;
166 return true;
167 }
168 return false;
169}
170
171bool FPDF_FileHandlerContext::Flush() {
172 if (!m_pFS || !m_pFS->Flush)
173 return true;
174
175 return m_pFS->Flush(m_pFS->clientData) == 0;
176}
177#endif // PDF_ENABLE_XFA
178
179} // namespace
180
Tom Sepez101535f2018-06-12 13:36:05 +0000181IPDF_Page* IPDFPageFromFPDFPage(FPDF_PAGE page) {
182 return reinterpret_cast<IPDF_Page*>(page);
Tom Sepez3f3c39d2018-05-01 17:46:34 +0000183}
184
Tom Sepez101535f2018-06-12 13:36:05 +0000185FPDF_PAGE FPDFPageFromIPDFPage(IPDF_Page* page) {
Tom Sepez3f3c39d2018-05-01 17:46:34 +0000186 return reinterpret_cast<FPDF_PAGE>(page);
Dan Sinclair7aba4722018-03-28 17:04:16 +0000187}
188
189CPDF_Document* CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc) {
Tom Sepezfe06d512018-05-01 17:25:25 +0000190 return reinterpret_cast<CPDF_Document*>(doc);
Dan Sinclair7aba4722018-03-28 17:04:16 +0000191}
192
193FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc) {
Tom Sepezfe06d512018-05-01 17:25:25 +0000194 return reinterpret_cast<FPDF_DOCUMENT>(doc);
Dan Sinclair7aba4722018-03-28 17:04:16 +0000195}
196
197CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
Tom Sepez101535f2018-06-12 13:36:05 +0000198 return page ? IPDFPageFromFPDFPage(page)->AsPDFPage() : nullptr;
Dan Sinclair7aba4722018-03-28 17:04:16 +0000199}
200
Lei Zhange6fcdfa2019-02-14 04:07:09 +0000201CPDFSDK_InteractiveForm* FormHandleToInteractiveForm(FPDF_FORMHANDLE hHandle) {
202 CPDFSDK_FormFillEnvironment* pFormFillEnv =
203 CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
204 return pFormFillEnv ? pFormFillEnv->GetInteractiveForm() : nullptr;
205}
206
Lei Zhangb46a7632019-01-09 02:56:16 +0000207ByteString ByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string) {
208 return WideStringFromFPDFWideString(wide_string).ToUTF8();
Dan Sinclair7aba4722018-03-28 17:04:16 +0000209}
210
Lei Zhangf5fcd9e2018-12-23 03:11:50 +0000211WideString WideStringFromFPDFWideString(FPDF_WIDESTRING wide_string) {
212 return WideString::FromUTF16LE(wide_string,
213 WideString::WStringLength(wide_string));
214}
215
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000216#ifdef PDF_ENABLE_XFA
217RetainPtr<IFX_SeekableStream> MakeSeekableStream(
218 FPDF_FILEHANDLER* pFilehandler) {
219 return pdfium::MakeRetain<FPDF_FileHandlerContext>(pFilehandler);
Dan Sinclair7aba4722018-03-28 17:04:16 +0000220}
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000221#endif // PDF_ENABLE_XFA
Dan Sinclair7aba4722018-03-28 17:04:16 +0000222
Lei Zhang5cee3f22018-05-25 21:48:49 +0000223const CPDF_Array* GetQuadPointsArrayFromDictionary(
224 const CPDF_Dictionary* dict) {
Lei Zhangd934c642019-03-04 19:42:00 +0000225 return dict->GetArrayFor("QuadPoints");
Lei Zhang5cee3f22018-05-25 21:48:49 +0000226}
227
Tom Sepez3d64afa2022-06-24 16:40:17 +0000228RetainPtr<CPDF_Array> GetMutableQuadPointsArrayFromDictionary(
229 CPDF_Dictionary* dict) {
230 return pdfium::WrapRetain(
231 const_cast<CPDF_Array*>(GetQuadPointsArrayFromDictionary(dict)));
Dan Sinclair7aba4722018-03-28 17:04:16 +0000232}
233
Ralf Sippl16381792018-04-12 21:20:26 +0000234CPDF_Array* AddQuadPointsArrayToDictionary(CPDF_Dictionary* dict) {
Ralf Sippl16381792018-04-12 21:20:26 +0000235 return dict->SetNewFor<CPDF_Array>(kQuadPoints);
236}
237
238bool IsValidQuadPointsIndex(const CPDF_Array* array, size_t index) {
Lei Zhangf40380f2018-10-12 18:31:51 +0000239 return array && index < array->size() / 8;
Ralf Sippl16381792018-04-12 21:20:26 +0000240}
241
242bool GetQuadPointsAtIndex(const CPDF_Array* array,
243 size_t quad_index,
244 FS_QUADPOINTSF* quad_points) {
Tom Sepez9c78c0d2021-01-27 20:13:14 +0000245 DCHECK(quad_points);
246 DCHECK(array);
Ralf Sippl16381792018-04-12 21:20:26 +0000247
248 if (!IsValidQuadPointsIndex(array, quad_index))
249 return false;
250
251 quad_index *= 8;
252 quad_points->x1 = array->GetNumberAt(quad_index);
253 quad_points->y1 = array->GetNumberAt(quad_index + 1);
254 quad_points->x2 = array->GetNumberAt(quad_index + 2);
255 quad_points->y2 = array->GetNumberAt(quad_index + 3);
256 quad_points->x3 = array->GetNumberAt(quad_index + 4);
257 quad_points->y3 = array->GetNumberAt(quad_index + 5);
258 quad_points->x4 = array->GetNumberAt(quad_index + 6);
259 quad_points->y4 = array->GetNumberAt(quad_index + 7);
260 return true;
261}
262
Lei Zhang8da98232019-12-11 23:29:33 +0000263CFX_PointF CFXPointFFromFSPointF(const FS_POINTF& point) {
264 return CFX_PointF(point.x, point.y);
265}
266
267CFX_FloatRect CFXFloatRectFromFSRectF(const FS_RECTF& rect) {
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000268 return CFX_FloatRect(rect.left, rect.bottom, rect.right, rect.top);
Dan Sinclair7aba4722018-03-28 17:04:16 +0000269}
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000270
Lei Zhang8da98232019-12-11 23:29:33 +0000271FS_RECTF FSRectFFromCFXFloatRect(const CFX_FloatRect& rect) {
Lei Zhang3567c612019-11-18 18:10:02 +0000272 return {rect.left, rect.top, rect.right, rect.bottom};
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000273}
274
Lei Zhang6fef1e42018-12-20 19:14:02 +0000275CFX_Matrix CFXMatrixFromFSMatrix(const FS_MATRIX& matrix) {
276 return CFX_Matrix(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
277}
278
Lei Zhangc89c5822020-01-21 20:23:56 +0000279FS_MATRIX FSMatrixFromCFXMatrix(const CFX_Matrix& matrix) {
280 return {matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f};
Lei Zhang8da98232019-12-11 23:29:33 +0000281}
282
Daniel Hosseinian5bc1f982020-04-14 01:05:27 +0000283unsigned long NulTerminateMaybeCopyAndReturnLength(const ByteString& text,
284 void* buffer,
285 unsigned long buflen) {
Tom Sepez8ef63b92022-03-08 19:53:34 +0000286 const unsigned long len =
287 pdfium::base::checked_cast<unsigned long>(text.GetLength() + 1);
Daniel Hosseinian5bc1f982020-04-14 01:05:27 +0000288 if (buffer && len <= buflen)
289 memcpy(buffer, text.c_str(), len);
290 return len;
291}
292
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000293unsigned long Utf16EncodeMaybeCopyAndReturnLength(const WideString& text,
294 void* buffer,
295 unsigned long buflen) {
296 ByteString encoded_text = text.ToUTF16LE();
Tom Sepez8ef63b92022-03-08 19:53:34 +0000297 const unsigned long len =
298 pdfium::base::checked_cast<unsigned long>(encoded_text.GetLength());
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000299 if (buffer && len <= buflen)
300 memcpy(buffer, encoded_text.c_str(), len);
301 return len;
302}
303
Jeremy Chinsen617a2e82019-06-20 00:11:12 +0000304unsigned long GetRawStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream,
305 void* buffer,
306 unsigned long buflen) {
307 return GetStreamMaybeCopyAndReturnLengthImpl(stream, buffer, buflen,
308 /*decode=*/false);
309}
310
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000311unsigned long DecodeStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream,
312 void* buffer,
313 unsigned long buflen) {
Jeremy Chinsen617a2e82019-06-20 00:11:12 +0000314 return GetStreamMaybeCopyAndReturnLengthImpl(stream, buffer, buflen,
315 /*decode=*/true);
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000316}
317
Tom Sepez69a4a702019-07-31 17:59:49 +0000318void SetPDFSandboxPolicy(FPDF_DWORD policy, FPDF_BOOL enable) {
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000319 switch (policy) {
320 case FPDF_POLICY_MACHINETIME_ACCESS: {
Tom Sepezfe285c32019-12-04 18:38:03 +0000321 uint32_t mask = 1 << policy;
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000322 if (enable)
Tom Sepezfe285c32019-12-04 18:38:03 +0000323 g_sandbox_policy |= mask;
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000324 else
Tom Sepezfe285c32019-12-04 18:38:03 +0000325 g_sandbox_policy &= ~mask;
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000326 } break;
327 default:
328 break;
329 }
330}
331
Tom Sepez69a4a702019-07-31 17:59:49 +0000332FPDF_BOOL IsPDFSandboxPolicyEnabled(FPDF_DWORD policy) {
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000333 switch (policy) {
Tom Sepezfe285c32019-12-04 18:38:03 +0000334 case FPDF_POLICY_MACHINETIME_ACCESS: {
335 uint32_t mask = 1 << policy;
336 return !!(g_sandbox_policy & mask);
337 }
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000338 default:
339 return false;
340 }
341}
342
Tom Sepez20c946f2019-07-31 19:33:21 +0000343void SetPDFUnsupportInfo(UNSUPPORT_INFO* unsp_info) {
344 g_unsupport_info = unsp_info;
345}
346
Lei Zhang4745a472020-02-27 18:24:58 +0000347void ReportUnsupportedFeatures(const CPDF_Document* pDoc) {
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000348 const CPDF_Dictionary* pRootDict = pDoc->GetRoot();
Lei Zhang4745a472020-02-27 18:24:58 +0000349 if (!pRootDict)
350 return;
351
352 // Portfolios and Packages
Lei Zhang6e8b20f2020-02-27 20:02:49 +0000353 if (pRootDict->KeyExist("Collection"))
Lei Zhang4745a472020-02-27 18:24:58 +0000354 RaiseUnsupportedError(FPDF_UNSP_DOC_PORTABLECOLLECTION);
Lei Zhang6e8b20f2020-02-27 20:02:49 +0000355
Lei Zhang4745a472020-02-27 18:24:58 +0000356 const CPDF_Dictionary* pNameDict = pRootDict->GetDictFor("Names");
357 if (pNameDict) {
Lei Zhang6e8b20f2020-02-27 20:02:49 +0000358 if (pNameDict->KeyExist("EmbeddedFiles"))
Lei Zhang4745a472020-02-27 18:24:58 +0000359 RaiseUnsupportedError(FPDF_UNSP_DOC_ATTACHMENT);
Lei Zhang6e8b20f2020-02-27 20:02:49 +0000360
Lei Zhang4745a472020-02-27 18:24:58 +0000361 const CPDF_Dictionary* pJSDict = pNameDict->GetDictFor("JavaScript");
362 if (pJSDict) {
363 const CPDF_Array* pArray = pJSDict->GetArrayFor("Names");
364 if (pArray) {
365 for (size_t i = 0; i < pArray->size(); i++) {
366 ByteString cbStr = pArray->GetStringAt(i);
Lei Zhang814e3bf2021-04-24 01:45:51 +0000367 if (cbStr == "com.adobe.acrobat.SharedReview.Register") {
Lei Zhang4745a472020-02-27 18:24:58 +0000368 RaiseUnsupportedError(FPDF_UNSP_DOC_SHAREDREVIEW);
Lei Zhang6e8b20f2020-02-27 20:02:49 +0000369 break;
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000370 }
371 }
372 }
373 }
Lei Zhang4745a472020-02-27 18:24:58 +0000374 }
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000375
Lei Zhang4745a472020-02-27 18:24:58 +0000376 // SharedForm
377 const CPDF_Stream* pStream = pRootDict->GetStreamFor("Metadata");
378 if (pStream) {
379 CPDF_Metadata metadata(pStream);
380 for (const UnsupportedFeature& feature : metadata.CheckForSharedForm())
381 RaiseUnsupportedError(static_cast<int>(feature));
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000382 }
Daniel Hosseiniana793e972020-01-24 02:51:31 +0000383}
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000384
Lei Zhang85e09df2020-02-27 14:48:07 +0000385void ReportUnsupportedXFA(const CPDF_Document* pDoc) {
386 if (!pDoc->GetExtension() && DocHasXFA(pDoc))
Lei Zhangb7d09ca2019-02-27 23:50:44 +0000387 RaiseUnsupportedError(FPDF_UNSP_DOC_XFAFORM);
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000388}
389
Lei Zhang4efdb512019-02-26 19:48:39 +0000390void CheckForUnsupportedAnnot(const CPDF_Annot* pAnnot) {
391 switch (pAnnot->GetSubtype()) {
392 case CPDF_Annot::Subtype::FILEATTACHMENT:
Lei Zhangb7d09ca2019-02-27 23:50:44 +0000393 RaiseUnsupportedError(FPDF_UNSP_ANNOT_ATTACHMENT);
Lei Zhang4efdb512019-02-26 19:48:39 +0000394 break;
395 case CPDF_Annot::Subtype::MOVIE:
Lei Zhangb7d09ca2019-02-27 23:50:44 +0000396 RaiseUnsupportedError(FPDF_UNSP_ANNOT_MOVIE);
Lei Zhang4efdb512019-02-26 19:48:39 +0000397 break;
398 case CPDF_Annot::Subtype::RICHMEDIA:
Lei Zhangb7d09ca2019-02-27 23:50:44 +0000399 RaiseUnsupportedError(FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA);
Lei Zhang4efdb512019-02-26 19:48:39 +0000400 break;
401 case CPDF_Annot::Subtype::SCREEN: {
402 const CPDF_Dictionary* pAnnotDict = pAnnot->GetAnnotDict();
Lei Zhang6c715022019-02-26 20:16:09 +0000403 ByteString cbString = pAnnotDict->GetStringFor("IT");
404 if (cbString != "Img")
Lei Zhangb7d09ca2019-02-27 23:50:44 +0000405 RaiseUnsupportedError(FPDF_UNSP_ANNOT_SCREEN_MEDIA);
Lei Zhang4efdb512019-02-26 19:48:39 +0000406 break;
407 }
408 case CPDF_Annot::Subtype::SOUND:
Lei Zhangb7d09ca2019-02-27 23:50:44 +0000409 RaiseUnsupportedError(FPDF_UNSP_ANNOT_SOUND);
Lei Zhang4efdb512019-02-26 19:48:39 +0000410 break;
411 case CPDF_Annot::Subtype::THREED:
Lei Zhangb7d09ca2019-02-27 23:50:44 +0000412 RaiseUnsupportedError(FPDF_UNSP_ANNOT_3DANNOT);
Lei Zhang4efdb512019-02-26 19:48:39 +0000413 break;
414 case CPDF_Annot::Subtype::WIDGET: {
415 const CPDF_Dictionary* pAnnotDict = pAnnot->GetAnnotDict();
Lei Zhang865ffb12019-02-26 20:18:19 +0000416 ByteString cbString = pAnnotDict->GetStringFor(pdfium::form_fields::kFT);
Lei Zhangf496e252019-02-26 20:20:19 +0000417 if (cbString == pdfium::form_fields::kSig)
Lei Zhangb7d09ca2019-02-27 23:50:44 +0000418 RaiseUnsupportedError(FPDF_UNSP_ANNOT_SIG);
Lei Zhang4efdb512019-02-26 19:48:39 +0000419 break;
420 }
421 default:
422 break;
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000423 }
424}
425
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000426void ProcessParseError(CPDF_Parser::Error err) {
427 uint32_t err_code = FPDF_ERR_SUCCESS;
428 // Translate FPDFAPI error code to FPDFVIEW error code
429 switch (err) {
430 case CPDF_Parser::SUCCESS:
431 err_code = FPDF_ERR_SUCCESS;
432 break;
433 case CPDF_Parser::FILE_ERROR:
434 err_code = FPDF_ERR_FILE;
435 break;
436 case CPDF_Parser::FORMAT_ERROR:
437 err_code = FPDF_ERR_FORMAT;
438 break;
439 case CPDF_Parser::PASSWORD_ERROR:
440 err_code = FPDF_ERR_PASSWORD;
441 break;
442 case CPDF_Parser::HANDLER_ERROR:
443 err_code = FPDF_ERR_SECURITY;
444 break;
445 }
Tom Sepez04e3af82019-08-05 23:41:06 +0000446 FXSYS_SetLastError(err_code);
Lei Zhang65a8d5e2018-12-20 19:13:21 +0000447}
Gourab Kundud35a62d2020-04-24 10:29:27 +0000448
449void SetColorFromScheme(const FPDF_COLORSCHEME* pColorScheme,
450 CPDF_RenderOptions* pRenderOptions) {
451 CPDF_RenderOptions::ColorScheme color_scheme;
Tom Sepez5ea5fa92022-03-08 00:15:23 +0000452 color_scheme.path_fill_color =
453 static_cast<FX_ARGB>(pColorScheme->path_fill_color);
454 color_scheme.path_stroke_color =
455 static_cast<FX_ARGB>(pColorScheme->path_stroke_color);
456 color_scheme.text_fill_color =
457 static_cast<FX_ARGB>(pColorScheme->text_fill_color);
458 color_scheme.text_stroke_color =
459 static_cast<FX_ARGB>(pColorScheme->text_stroke_color);
Gourab Kundud35a62d2020-04-24 10:29:27 +0000460 pRenderOptions->SetColorScheme(color_scheme);
461}
Tom Sepezc524b1f2021-04-06 00:09:39 +0000462
463std::vector<uint32_t> ParsePageRangeString(const ByteString& bsPageRange,
464 uint32_t nCount) {
Tom Sepez1e2d7df2021-04-07 19:26:06 +0000465 ByteStringView alphabet(" 0123456789-,");
466 for (const auto& ch : bsPageRange) {
467 if (!alphabet.Contains(ch))
Tom Sepezc524b1f2021-04-06 00:09:39 +0000468 return std::vector<uint32_t>();
469 }
470
Tom Sepez1e2d7df2021-04-07 19:26:06 +0000471 ByteString bsStrippedPageRange = bsPageRange;
472 bsStrippedPageRange.Remove(' ');
Tom Sepezc524b1f2021-04-06 00:09:39 +0000473
Tom Sepez1e2d7df2021-04-07 19:26:06 +0000474 std::vector<uint32_t> results;
475 for (const auto& entry : fxcrt::Split(bsStrippedPageRange, ',')) {
476 std::vector<ByteString> args = fxcrt::Split(entry, '-');
477 if (args.size() == 1) {
478 uint32_t page_num =
479 pdfium::base::checked_cast<uint32_t>(atoi(args[0].c_str()));
480 if (page_num == 0 || page_num > nCount)
Tom Sepezc524b1f2021-04-06 00:09:39 +0000481 return std::vector<uint32_t>();
Daniel Hosseinianc7cb4052021-06-11 21:00:47 +0000482 results.push_back(page_num - 1);
Tom Sepez1e2d7df2021-04-07 19:26:06 +0000483 } else if (args.size() == 2) {
484 uint32_t first_num =
485 pdfium::base::checked_cast<uint32_t>(atoi(args[0].c_str()));
486 if (first_num == 0)
Tom Sepezc524b1f2021-04-06 00:09:39 +0000487 return std::vector<uint32_t>();
Tom Sepez1e2d7df2021-04-07 19:26:06 +0000488 uint32_t last_num =
489 pdfium::base::checked_cast<uint32_t>(atoi(args[1].c_str()));
490 if (last_num == 0 || first_num > last_num || last_num > nCount)
491 return std::vector<uint32_t>();
492 for (uint32_t i = first_num; i <= last_num; ++i)
Daniel Hosseinianc7cb4052021-06-11 21:00:47 +0000493 results.push_back(i - 1);
Tom Sepezc524b1f2021-04-06 00:09:39 +0000494 } else {
Tom Sepez1e2d7df2021-04-07 19:26:06 +0000495 return std::vector<uint32_t>();
Tom Sepezc524b1f2021-04-06 00:09:39 +0000496 }
Tom Sepezc524b1f2021-04-06 00:09:39 +0000497 }
Tom Sepez1e2d7df2021-04-07 19:26:06 +0000498 return results;
Tom Sepezc524b1f2021-04-06 00:09:39 +0000499}