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_basic.h"
18 #include "core/fxcrt/fx_memory.h"
19 #include "core/fxcrt/fx_xml.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 DLLEXPORT FPDF_BOOL STDCALL
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 CFX_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 CFX_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,CFX_ByteString cbName)78 bool CheckSharedForm(const CXML_Element* pElement, CFX_ByteString cbName) {
79 int count = pElement->CountAttrs();
80 int i = 0;
81 for (i = 0; i < count; i++) {
82 CFX_ByteString space, name;
83 CFX_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.AsStringC());
89 if (!pVersion)
90 continue;
91 CFX_WideString wsContent = pVersion->GetContent(0);
92 int nType = wsContent.GetInteger();
93 switch (nType) {
94 case 1:
95 FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_ACROBAT);
96 break;
97 case 2:
98 FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM);
99 break;
100 case 0:
101 FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_EMAIL);
102 break;
103 }
104 }
105 }
106
107 uint32_t nCount = pElement->CountChildren();
108 for (i = 0; i < (int)nCount; i++) {
109 CXML_Element::ChildType childType = pElement->GetChildType(i);
110 if (childType == CXML_Element::Element) {
111 CXML_Element* pChild = pElement->GetElement(i);
112 if (CheckSharedForm(pChild, cbName))
113 return true;
114 }
115 }
116 return false;
117 }
118
CheckUnSupportError(CPDF_Document * pDoc,uint32_t err_code)119 void CheckUnSupportError(CPDF_Document* pDoc, uint32_t err_code) {
120 // Security
121 if (err_code == FPDF_ERR_SECURITY) {
122 FPDF_UnSupportError(FPDF_UNSP_DOC_SECURITY);
123 return;
124 }
125 if (!pDoc)
126 return;
127
128 // Portfolios and Packages
129 CPDF_Dictionary* pRootDict = pDoc->GetRoot();
130 if (pRootDict) {
131 CFX_ByteString cbString;
132 if (pRootDict->KeyExist("Collection")) {
133 FPDF_UnSupportError(FPDF_UNSP_DOC_PORTABLECOLLECTION);
134 return;
135 }
136 if (pRootDict->KeyExist("Names")) {
137 CPDF_Dictionary* pNameDict = pRootDict->GetDictFor("Names");
138 if (pNameDict && pNameDict->KeyExist("EmbeddedFiles")) {
139 FPDF_UnSupportError(FPDF_UNSP_DOC_ATTACHMENT);
140 return;
141 }
142 if (pNameDict && pNameDict->KeyExist("JavaScript")) {
143 CPDF_Dictionary* pJSDict = pNameDict->GetDictFor("JavaScript");
144 CPDF_Array* pArray = pJSDict ? pJSDict->GetArrayFor("Names") : nullptr;
145 if (pArray) {
146 for (size_t i = 0; i < pArray->GetCount(); i++) {
147 CFX_ByteString cbStr = pArray->GetStringAt(i);
148 if (cbStr.Compare("com.adobe.acrobat.SharedReview.Register") == 0) {
149 FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDREVIEW);
150 return;
151 }
152 }
153 }
154 }
155 }
156 }
157
158 // SharedForm
159 CPDF_Metadata metaData(pDoc);
160 const CXML_Element* pElement = metaData.GetRoot();
161 if (pElement)
162 CheckSharedForm(pElement, "workflowType");
163
164 #ifndef PDF_ENABLE_XFA
165 // XFA Forms
166 CPDF_InterForm interform(pDoc);
167 if (interform.HasXFAForm())
168 FPDF_UnSupportError(FPDF_UNSP_DOC_XFAFORM);
169 #endif // PDF_ENABLE_XFA
170 }
171
FPDFDoc_GetPageMode(FPDF_DOCUMENT document)172 DLLEXPORT int STDCALL FPDFDoc_GetPageMode(FPDF_DOCUMENT document) {
173 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
174 if (!pDoc)
175 return PAGEMODE_UNKNOWN;
176
177 CPDF_Dictionary* pRoot = pDoc->GetRoot();
178 if (!pRoot)
179 return PAGEMODE_UNKNOWN;
180
181 CPDF_Object* pName = pRoot->GetObjectFor("PageMode");
182 if (!pName)
183 return PAGEMODE_USENONE;
184
185 CFX_ByteString strPageMode = pName->GetString();
186 if (strPageMode.IsEmpty() || strPageMode.EqualNoCase("UseNone"))
187 return PAGEMODE_USENONE;
188 if (strPageMode.EqualNoCase("UseOutlines"))
189 return PAGEMODE_USEOUTLINES;
190 if (strPageMode.EqualNoCase("UseThumbs"))
191 return PAGEMODE_USETHUMBS;
192 if (strPageMode.EqualNoCase("FullScreen"))
193 return PAGEMODE_FULLSCREEN;
194 if (strPageMode.EqualNoCase("UseOC"))
195 return PAGEMODE_USEOC;
196 if (strPageMode.EqualNoCase("UseAttachments"))
197 return PAGEMODE_USEATTACHMENTS;
198
199 return PAGEMODE_UNKNOWN;
200 }
201