1 // 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.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "public/fpdf_ext.h"
8
9 #include <memory>
10
11 #include "core/fpdfapi/cpdf_modulemgr.h"
12 #include "core/fpdfapi/parser/cpdf_array.h"
13 #include "core/fpdfapi/parser/cpdf_document.h"
14 #include "core/fpdfdoc/cpdf_annot.h"
15 #include "core/fpdfdoc/cpdf_interform.h"
16 #include "core/fpdfdoc/cpdf_metadata.h"
17 #include "core/fxcrt/fx_memory.h"
18 #include "core/fxcrt/xml/cxml_content.h"
19 #include "core/fxcrt/xml/cxml_element.h"
20 #include "fpdfsdk/fsdk_define.h"
21 #include "third_party/base/ptr_util.h"
22
23 #ifdef PDF_ENABLE_XFA
24 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
25 #endif // PDF_ENABLE_XFA
26
FPDF_UnSupportError(int nError)27 bool FPDF_UnSupportError(int nError) {
28 CFSDK_UnsupportInfo_Adapter* pAdapter =
29 CPDF_ModuleMgr::Get()->GetUnsupportInfoAdapter();
30 if (!pAdapter)
31 return false;
32
33 UNSUPPORT_INFO* info = static_cast<UNSUPPORT_INFO*>(pAdapter->GetUnspInfo());
34 if (info && info->FSDK_UnSupport_Handler)
35 info->FSDK_UnSupport_Handler(info, nError);
36 return true;
37 }
38
39 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FSDK_SetUnSpObjProcessHandler(UNSUPPORT_INFO * unsp_info)40 FSDK_SetUnSpObjProcessHandler(UNSUPPORT_INFO* unsp_info) {
41 if (!unsp_info || unsp_info->version != 1)
42 return false;
43
44 CPDF_ModuleMgr::Get()->SetUnsupportInfoAdapter(
45 pdfium::MakeUnique<CFSDK_UnsupportInfo_Adapter>(unsp_info));
46 return true;
47 }
48
CheckUnSupportAnnot(CPDF_Document * pDoc,const CPDF_Annot * pPDFAnnot)49 void CheckUnSupportAnnot(CPDF_Document* pDoc, const CPDF_Annot* pPDFAnnot) {
50 CPDF_Annot::Subtype nAnnotSubtype = pPDFAnnot->GetSubtype();
51 if (nAnnotSubtype == CPDF_Annot::Subtype::THREED) {
52 FPDF_UnSupportError(FPDF_UNSP_ANNOT_3DANNOT);
53 } else if (nAnnotSubtype == CPDF_Annot::Subtype::SCREEN) {
54 const CPDF_Dictionary* pAnnotDict = pPDFAnnot->GetAnnotDict();
55 ByteString cbString;
56 if (pAnnotDict->KeyExist("IT"))
57 cbString = pAnnotDict->GetStringFor("IT");
58 if (cbString.Compare("Img") != 0)
59 FPDF_UnSupportError(FPDF_UNSP_ANNOT_SCREEN_MEDIA);
60 } else if (nAnnotSubtype == CPDF_Annot::Subtype::MOVIE) {
61 FPDF_UnSupportError(FPDF_UNSP_ANNOT_MOVIE);
62 } else if (nAnnotSubtype == CPDF_Annot::Subtype::SOUND) {
63 FPDF_UnSupportError(FPDF_UNSP_ANNOT_SOUND);
64 } else if (nAnnotSubtype == CPDF_Annot::Subtype::RICHMEDIA) {
65 FPDF_UnSupportError(FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA);
66 } else if (nAnnotSubtype == CPDF_Annot::Subtype::FILEATTACHMENT) {
67 FPDF_UnSupportError(FPDF_UNSP_ANNOT_ATTACHMENT);
68 } else if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET) {
69 const CPDF_Dictionary* pAnnotDict = pPDFAnnot->GetAnnotDict();
70 ByteString cbString;
71 if (pAnnotDict->KeyExist("FT"))
72 cbString = pAnnotDict->GetStringFor("FT");
73 if (cbString.Compare("Sig") == 0)
74 FPDF_UnSupportError(FPDF_UNSP_ANNOT_SIG);
75 }
76 }
77
CheckSharedForm(const CXML_Element * pElement,ByteString cbName)78 bool CheckSharedForm(const CXML_Element* pElement, ByteString cbName) {
79 size_t count = pElement->CountAttrs();
80 for (size_t i = 0; i < count; ++i) {
81 ByteString space;
82 ByteString name;
83 WideString value;
84 pElement->GetAttrByIndex(i, &space, &name, &value);
85 if (space == "xmlns" && name == "adhocwf" &&
86 value == L"http://ns.adobe.com/AcrobatAdhocWorkflow/1.0/") {
87 CXML_Element* pVersion =
88 pElement->GetElement("adhocwf", cbName.AsStringView(), 0);
89 if (!pVersion)
90 continue;
91 CXML_Content* pContent = ToContent(pVersion->GetChild(0));
92 if (!pContent)
93 continue;
94 switch (pContent->m_Content.GetInteger()) {
95 case 1:
96 FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_ACROBAT);
97 break;
98 case 2:
99 FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM);
100 break;
101 case 0:
102 FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_EMAIL);
103 break;
104 }
105 }
106 }
107
108 size_t nCount = pElement->CountChildren();
109 for (size_t i = 0; i < nCount; ++i) {
110 CXML_Element* pChild = ToElement(pElement->GetChild(i));
111 if (pChild && CheckSharedForm(pChild, cbName))
112 return true;
113 }
114 return false;
115 }
116
CheckUnSupportError(CPDF_Document * pDoc,uint32_t err_code)117 void CheckUnSupportError(CPDF_Document* pDoc, uint32_t err_code) {
118 // Security
119 if (err_code == FPDF_ERR_SECURITY) {
120 FPDF_UnSupportError(FPDF_UNSP_DOC_SECURITY);
121 return;
122 }
123 if (!pDoc)
124 return;
125
126 // Portfolios and Packages
127 const CPDF_Dictionary* pRootDict = pDoc->GetRoot();
128 if (pRootDict) {
129 ByteString cbString;
130 if (pRootDict->KeyExist("Collection")) {
131 FPDF_UnSupportError(FPDF_UNSP_DOC_PORTABLECOLLECTION);
132 return;
133 }
134 if (pRootDict->KeyExist("Names")) {
135 CPDF_Dictionary* pNameDict = pRootDict->GetDictFor("Names");
136 if (pNameDict && pNameDict->KeyExist("EmbeddedFiles")) {
137 FPDF_UnSupportError(FPDF_UNSP_DOC_ATTACHMENT);
138 return;
139 }
140 if (pNameDict && pNameDict->KeyExist("JavaScript")) {
141 CPDF_Dictionary* pJSDict = pNameDict->GetDictFor("JavaScript");
142 CPDF_Array* pArray = pJSDict ? pJSDict->GetArrayFor("Names") : nullptr;
143 if (pArray) {
144 for (size_t i = 0; i < pArray->GetCount(); i++) {
145 ByteString cbStr = pArray->GetStringAt(i);
146 if (cbStr.Compare("com.adobe.acrobat.SharedReview.Register") == 0) {
147 FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDREVIEW);
148 return;
149 }
150 }
151 }
152 }
153 }
154 }
155
156 // SharedForm
157 CPDF_Metadata metaData(pDoc);
158 const CXML_Element* pElement = metaData.GetRoot();
159 if (pElement)
160 CheckSharedForm(pElement, "workflowType");
161
162 #ifndef PDF_ENABLE_XFA
163 // XFA Forms
164 CPDF_InterForm interform(pDoc);
165 if (interform.HasXFAForm())
166 FPDF_UnSupportError(FPDF_UNSP_DOC_XFAFORM);
167 #endif // PDF_ENABLE_XFA
168 }
169
FPDFDoc_GetPageMode(FPDF_DOCUMENT document)170 FPDF_EXPORT int FPDF_CALLCONV FPDFDoc_GetPageMode(FPDF_DOCUMENT document) {
171 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
172 if (!pDoc)
173 return PAGEMODE_UNKNOWN;
174
175 const CPDF_Dictionary* pRoot = pDoc->GetRoot();
176 if (!pRoot)
177 return PAGEMODE_UNKNOWN;
178
179 CPDF_Object* pName = pRoot->GetObjectFor("PageMode");
180 if (!pName)
181 return PAGEMODE_USENONE;
182
183 ByteString strPageMode = pName->GetString();
184 if (strPageMode.IsEmpty() || strPageMode.EqualNoCase("UseNone"))
185 return PAGEMODE_USENONE;
186 if (strPageMode.EqualNoCase("UseOutlines"))
187 return PAGEMODE_USEOUTLINES;
188 if (strPageMode.EqualNoCase("UseThumbs"))
189 return PAGEMODE_USETHUMBS;
190 if (strPageMode.EqualNoCase("FullScreen"))
191 return PAGEMODE_FULLSCREEN;
192 if (strPageMode.EqualNoCase("UseOC"))
193 return PAGEMODE_USEOC;
194 if (strPageMode.EqualNoCase("UseAttachments"))
195 return PAGEMODE_USEATTACHMENTS;
196
197 return PAGEMODE_UNKNOWN;
198 }
199