7#include "fpdfsdk/cpdfsdk_helpers.h"
11#include "build/build_config.h"
12#include "constants/form_fields.h"
13#include "constants/stream_dict_common.h"
14#include "core/fpdfapi/page/cpdf_page.h"
15#include "core/fpdfapi/parser/cpdf_array.h"
16#include "core/fpdfapi/parser/cpdf_dictionary.h"
17#include "core/fpdfapi/parser/cpdf_document.h"
18#include "core/fpdfapi/parser/cpdf_stream_acc.h"
19#include "core/fpdfapi/render/cpdf_renderoptions.h"
20#include "core/fpdfdoc/cpdf_annot.h"
21#include "core/fpdfdoc/cpdf_interactiveform.h"
22#include "core/fpdfdoc/cpdf_metadata.h"
23#include "core/fxcrt/span_util.h"
24#include "core/fxcrt/unowned_ptr.h"
25#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
26#include "third_party/base/check.h"
27#include "third_party/base/numerics/safe_conversions.h"
31constexpr char kQuadPoints[] =
"QuadPoints";
34uint32_t g_sandbox_policy = 0xFFFFFFFF;
36UNSUPPORT_INFO* g_unsupport_info =
nullptr;
38bool RaiseUnsupportedError(
int nError) {
39 if (!g_unsupport_info)
53 RetainPtr<
const CPDF_Dictionary> form = root->GetDictFor(
"AcroForm");
54 return form && form->GetArrayFor(
"XFA");
57unsigned long GetStreamMaybeCopyAndReturnLengthImpl(
59 pdfium::span<uint8_t> buffer,
62 auto stream_acc = pdfium::MakeRetain<CPDF_StreamAcc>(
std::move(stream));
64 stream_acc->LoadAllDataFiltered();
66 stream_acc->LoadAllDataRaw();
68 pdfium::span<
const uint8_t> stream_data_span = stream_acc->GetSpan();
69 if (!buffer.empty() && buffer.size() <= stream_data_span.size())
70 fxcrt::spancpy(buffer, stream_data_span);
72 return pdfium::base::checked_cast<
unsigned long>(stream_data_span.size());
76class FPDF_FileHandlerContext final :
public IFX_SeekableStream {
78 CONSTRUCT_VIA_MAKE_RETAIN;
81 FX_FILESIZE GetSize() override;
82 FX_FILESIZE GetPosition() override;
83 bool IsEOF() override;
84 size_t ReadBlock(pdfium::span<uint8_t> buffer) override;
85 bool ReadBlockAtOffset(pdfium::span<uint8_t> buffer,
86 FX_FILESIZE offset) override;
87 bool WriteBlockAtOffset(pdfium::span<
const uint8_t> buffer,
88 FX_FILESIZE offset) override;
89 bool Flush() override;
91 void SetPosition(FX_FILESIZE pos) { m_nCurPos = pos; }
94 explicit FPDF_FileHandlerContext(FPDF_FILEHANDLER* pFS);
95 ~FPDF_FileHandlerContext() override;
97 UnownedPtr<FPDF_FILEHANDLER>
const m_pFS;
98 FX_FILESIZE m_nCurPos = 0;
101FPDF_FileHandlerContext::FPDF_FileHandlerContext(FPDF_FILEHANDLER* pFS)
104FPDF_FileHandlerContext::~FPDF_FileHandlerContext() {
105 if (m_pFS && m_pFS->Release)
106 m_pFS->Release(m_pFS->clientData);
109FX_FILESIZE FPDF_FileHandlerContext::GetSize() {
110 if (m_pFS && m_pFS->GetSize)
111 return static_cast<FX_FILESIZE>(m_pFS->GetSize(m_pFS->clientData));
115bool FPDF_FileHandlerContext::IsEOF() {
116 return m_nCurPos >= GetSize();
119FX_FILESIZE FPDF_FileHandlerContext::GetPosition() {
123bool FPDF_FileHandlerContext::ReadBlockAtOffset(pdfium::span<uint8_t> buffer,
124 FX_FILESIZE offset) {
125 if (buffer.empty() || !m_pFS->ReadBlock)
128 if (m_pFS->ReadBlock(m_pFS->clientData,
static_cast<FPDF_DWORD>(offset),
130 static_cast<FPDF_DWORD>(buffer.size())) == 0) {
131 m_nCurPos = offset + buffer.size();
137size_t FPDF_FileHandlerContext::ReadBlock(pdfium::span<uint8_t> buffer) {
138 if (buffer.empty() || !m_pFS->ReadBlock)
141 FX_FILESIZE nSize = GetSize();
142 if (m_nCurPos >= nSize)
144 FX_FILESIZE dwAvail = nSize - m_nCurPos;
145 if (dwAvail < (FX_FILESIZE)buffer.size())
146 buffer = buffer.first(
static_cast<size_t>(dwAvail));
147 if (m_pFS->ReadBlock(m_pFS->clientData,
static_cast<FPDF_DWORD>(m_nCurPos),
149 static_cast<FPDF_DWORD>(buffer.size())) == 0) {
150 m_nCurPos += buffer.size();
151 return buffer.size();
157bool FPDF_FileHandlerContext::WriteBlockAtOffset(
158 pdfium::span<
const uint8_t> buffer,
159 FX_FILESIZE offset) {
160 if (!m_pFS || !m_pFS->WriteBlock)
163 if (m_pFS->WriteBlock(m_pFS->clientData,
static_cast<FPDF_DWORD>(offset),
165 static_cast<FPDF_DWORD>(buffer.size())) == 0) {
166 m_nCurPos = offset + buffer.size();
172bool FPDF_FileHandlerContext::Flush() {
173 if (!m_pFS || !m_pFS->Flush)
176 return m_pFS->Flush(m_pFS->clientData) == 0;
183 return reinterpret_cast<
IPDF_Page*>(page);
187 return reinterpret_cast<FPDF_PAGE>(page);
195 return reinterpret_cast<FPDF_DOCUMENT>(doc);
203 CPDFSDK_FormFillEnvironment* pFormFillEnv =
213 return WideString
::FromUTF16LE({
reinterpret_cast<
const uint8_t*>(wide_string),
214 WideString::WStringLength(wide_string) * 2}
);
218RetainPtr<IFX_SeekableStream> MakeSeekableStream(
219 FPDF_FILEHANDLER* pFilehandler) {
220 return pdfium::MakeRetain<FPDF_FileHandlerContext>(pFilehandler);
225 const CPDF_Dictionary* dict) {
230 CPDF_Dictionary* dict) {
231 return pdfium::WrapRetain(
232 const_cast<CPDF_Array*>(GetQuadPointsArrayFromDictionary(dict).Get()));
236 return dict->SetNewFor<CPDF_Array>(kQuadPoints);
240 return array && index < array->size() / 8;
245 FS_QUADPOINTSF* quad_points) {
249 if (!IsValidQuadPointsIndex(array, quad_index))
253 quad_points->x1 = array->GetFloatAt(quad_index);
254 quad_points->y1 = array->GetFloatAt(quad_index + 1);
255 quad_points->x2 = array->GetFloatAt(quad_index + 2);
256 quad_points->y2 = array->GetFloatAt(quad_index + 3);
257 quad_points->x3 = array->GetFloatAt(quad_index + 4);
258 quad_points->y3 = array->GetFloatAt(quad_index + 5);
259 quad_points->x4 = array->GetFloatAt(quad_index + 6);
260 quad_points->y4 = array->GetFloatAt(quad_index + 7);
265 return CFX_PointF(point.x, point.y);
281 return {matrix
.a, matrix
.b, matrix
.c, matrix
.d, matrix
.e, matrix
.f};
286 unsigned long buflen) {
287 const unsigned long len =
288 pdfium::base::checked_cast<
unsigned long>(text.GetLength() + 1);
289 if (buffer && len <= buflen)
296 unsigned long buflen) {
298 const unsigned long len =
299 pdfium::base::checked_cast<
unsigned long>(encoded_text.GetLength());
300 if (buffer && len <= buflen)
301 memcpy(buffer, encoded_text
.c_str(), len);
307 pdfium::span<uint8_t> buffer) {
308 return GetStreamMaybeCopyAndReturnLengthImpl(
std::move(stream), buffer,
314 pdfium::span<uint8_t> buffer) {
315 return GetStreamMaybeCopyAndReturnLengthImpl(
std::move(stream), buffer,
322 uint32_t mask = 1 << policy;
324 g_sandbox_policy |= mask;
326 g_sandbox_policy &= ~mask;
336 uint32_t mask = 1 << policy;
337 return !!(g_sandbox_policy & mask);
345 g_unsupport_info = unsp_info;
349 const CPDF_Dictionary* pRootDict = pDoc
->GetRoot();
357 RetainPtr<
const CPDF_Dictionary> pNameDict = pRootDict->GetDictFor(
"Names");
359 if (pNameDict->KeyExist(
"EmbeddedFiles"))
362 RetainPtr<
const CPDF_Dictionary> pJSDict =
363 pNameDict->GetDictFor(
"JavaScript");
365 RetainPtr<
const CPDF_Array> pArray = pJSDict->GetArrayFor(
"Names");
367 for (size_t i = 0; i < pArray->size(); i++) {
368 ByteString cbStr = pArray->GetByteStringAt(i);
369 if (cbStr
== "com.adobe.acrobat.SharedReview.Register") {
379 RetainPtr<
const CPDF_Stream> pStream = pRootDict->GetStreamFor(
"Metadata");
382 for (
const UnsupportedFeature& feature : metadata.CheckForSharedForm())
383 RaiseUnsupportedError(
static_cast<
int>(feature));
406 if (cbString
!= "Img")
418 ByteString cbString =
456 static_cast<FX_ARGB>(pColorScheme->path_fill_color);
458 static_cast<FX_ARGB>(pColorScheme->path_stroke_color);
460 static_cast<FX_ARGB>(pColorScheme->text_fill_color);
462 static_cast<FX_ARGB>(pColorScheme->text_stroke_color);
468 ByteStringView alphabet(
" 0123456789-,");
469 for (
const auto& ch : bsPageRange) {
470 if (!alphabet.Contains(ch))
471 return std::vector<uint32_t>();
474 ByteString bsStrippedPageRange = bsPageRange;
475 bsStrippedPageRange.Remove(
' ');
477 std::vector<uint32_t> results;
478 for (
const auto& entry : fxcrt::Split(bsStrippedPageRange,
',')) {
479 std::vector<ByteString> args = fxcrt::Split(entry,
'-');
480 if (args.size() == 1) {
482 pdfium::base::checked_cast<uint32_t>(atoi(args[0].c_str()));
483 if (page_num == 0 || page_num > nCount)
484 return std::vector<uint32_t>();
485 results.push_back(page_num - 1);
486 }
else if (args.size() == 2) {
488 pdfium::base::checked_cast<uint32_t>(atoi(args[0].c_str()));
490 return std::vector<uint32_t>();
492 pdfium::base::checked_cast<uint32_t>(atoi(args[1].c_str()));
493 if (last_num == 0 || first_num > last_num || last_num > nCount)
494 return std::vector<uint32_t>();
495 for (uint32_t i = first_num; i <= last_num; ++i)
496 results.push_back(i - 1);
498 return std::vector<uint32_t>();
constexpr CFX_FloatRect(float l, float b, float r, float t)
CFX_Matrix(float a1, float b1, float c1, float d1, float e1, float f1)
Subtype GetSubtype() const
const CPDF_Dictionary * GetAnnotDict() const
bool KeyExist(const ByteString &key) const
ByteString GetByteStringFor(const ByteString &key) const
RetainPtr< const CPDF_Array > GetArrayFor(const ByteString &key) const
Extension * GetExtension() const
const CPDF_Dictionary * GetRoot() const
void SetColorScheme(const ColorScheme &color_scheme)
virtual CPDF_Page * AsPDFPage()=0
bool operator==(const char *ptr) const
const char * c_str() const
bool operator!=(const char *ptr) const
ByteString ToUTF8() const
static WideString FromUTF16LE(pdfium::span< const uint8_t > data)
ByteString ToUTF16LE() const
WideString WideStringFromFPDFWideString(FPDF_WIDESTRING wide_string)
bool IsValidQuadPointsIndex(const CPDF_Array *array, size_t index)
std::vector< uint32_t > ParsePageRangeString(const ByteString &bsPageRange, uint32_t nCount)
unsigned long NulTerminateMaybeCopyAndReturnLength(const ByteString &text, void *buffer, unsigned long buflen)
ByteString ByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string)
IPDF_Page * IPDFPageFromFPDFPage(FPDF_PAGE page)
FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document *doc)
void ProcessParseError(CPDF_Parser::Error err)
RetainPtr< CPDF_Array > AddQuadPointsArrayToDictionary(CPDF_Dictionary *dict)
unsigned long Utf16EncodeMaybeCopyAndReturnLength(const WideString &text, void *buffer, unsigned long buflen)
FPDF_BOOL IsPDFSandboxPolicyEnabled(FPDF_DWORD policy)
CPDFSDK_FormFillEnvironment * CPDFSDKFormFillEnvironmentFromFPDFFormHandle(FPDF_FORMHANDLE handle)
void SetPDFSandboxPolicy(FPDF_DWORD policy, FPDF_BOOL enable)
RetainPtr< const CPDF_Array > GetQuadPointsArrayFromDictionary(const CPDF_Dictionary *dict)
bool GetQuadPointsAtIndex(RetainPtr< const CPDF_Array > array, size_t quad_index, FS_QUADPOINTSF *quad_points)
void ReportUnsupportedXFA(const CPDF_Document *pDoc)
FS_RECTF FSRectFFromCFXFloatRect(const CFX_FloatRect &rect)
RetainPtr< CPDF_Array > GetMutableQuadPointsArrayFromDictionary(CPDF_Dictionary *dict)
void CheckForUnsupportedAnnot(const CPDF_Annot *pAnnot)
void ReportUnsupportedFeatures(const CPDF_Document *pDoc)
FS_MATRIX FSMatrixFromCFXMatrix(const CFX_Matrix &matrix)
void SetColorFromScheme(const FPDF_COLORSCHEME *pColorScheme, CPDF_RenderOptions *pRenderOptions)
CFX_FloatRect CFXFloatRectFromFSRectF(const FS_RECTF &rect)
FPDF_PAGE FPDFPageFromIPDFPage(IPDF_Page *page)
unsigned long GetRawStreamMaybeCopyAndReturnLength(RetainPtr< const CPDF_Stream > stream, pdfium::span< uint8_t > buffer)
CFX_PointF CFXPointFFromFSPointF(const FS_POINTF &point)
CPDF_Page * CPDFPageFromFPDFPage(FPDF_PAGE page)
CPDF_Document * CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc)
unsigned long DecodeStreamMaybeCopyAndReturnLength(RetainPtr< const CPDF_Stream > stream, pdfium::span< uint8_t > buffer)
void SetPDFUnsupportInfo(UNSUPPORT_INFO *unsp_info)
CFX_Matrix CFXMatrixFromFSMatrix(const FS_MATRIX &matrix)
CPDFSDK_InteractiveForm * FormHandleToInteractiveForm(FPDF_FORMHANDLE hHandle)
#define FPDF_UNSP_DOC_PORTABLECOLLECTION
#define FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA
#define FPDF_UNSP_ANNOT_ATTACHMENT
#define FPDF_UNSP_DOC_ATTACHMENT
#define FPDF_UNSP_ANNOT_SIG
#define FPDF_UNSP_ANNOT_SOUND
#define FPDF_UNSP_DOC_XFAFORM
#define FPDF_UNSP_ANNOT_3DANNOT
#define FPDF_UNSP_ANNOT_MOVIE
#define FPDF_UNSP_ANNOT_SCREEN_MEDIA
#define FPDF_UNSP_DOC_SHAREDREVIEW
#define FPDF_ERR_SECURITY
#define FPDF_ERR_PASSWORD
#define FPDF_POLICY_MACHINETIME_ACCESS
void FXSYS_SetLastError(uint32_t err)
FX_ARGB path_stroke_color
FX_ARGB text_stroke_color
void(* FSDK_UnSupport_Handler)(struct _UNSUPPORT_INFO *pThis, int nType)