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 "../include/fsdk_define.h"
8#include "../include/fpdf_ext.h"
9
10#define  FPDFSDK_UNSUPPORT_CALL 100
11
12class CFSDK_UnsupportInfo_Adapter
13{
14public:
15	CFSDK_UnsupportInfo_Adapter(UNSUPPORT_INFO* unsp_info){ m_unsp_info = unsp_info;}
16//	FX_BOOL NeedToPauseNow();
17	void ReportError(int nErrorType);
18
19private:
20	UNSUPPORT_INFO* m_unsp_info;
21};
22
23void CFSDK_UnsupportInfo_Adapter::ReportError(int nErrorType)
24{
25	if(m_unsp_info && m_unsp_info->FSDK_UnSupport_Handler)
26	{
27		m_unsp_info->FSDK_UnSupport_Handler(m_unsp_info,nErrorType);
28	}
29}
30
31void FreeUnsupportInfo(FX_LPVOID pData)
32{
33	CFSDK_UnsupportInfo_Adapter * pAdapter = (CFSDK_UnsupportInfo_Adapter *)pData;
34	delete pAdapter;
35}
36
37FX_BOOL FPDF_UnSupportError(int nError)
38{
39	CFSDK_UnsupportInfo_Adapter * pAdapter = (CFSDK_UnsupportInfo_Adapter *)CPDF_ModuleMgr::Get()->GetPrivateData((void *)FPDFSDK_UNSUPPORT_CALL);
40
41	if(!pAdapter)
42		return FALSE;
43	pAdapter->ReportError(nError);
44	return TRUE;
45}
46
47DLLEXPORT FPDF_BOOL STDCALL FSDK_SetUnSpObjProcessHandler(UNSUPPORT_INFO* unsp_info)
48{
49	if (!unsp_info || unsp_info->version!=1)
50		return FALSE;
51	CFSDK_UnsupportInfo_Adapter * pAdapter = new CFSDK_UnsupportInfo_Adapter(unsp_info);
52
53	CPDF_ModuleMgr::Get()->SetPrivateData((void *)FPDFSDK_UNSUPPORT_CALL,pAdapter, &FreeUnsupportInfo);
54
55	return TRUE;
56}
57
58void CheckUnSupportAnnot(CPDF_Document * pDoc, CPDF_Annot* pPDFAnnot)
59{
60	CFX_ByteString cbSubType = pPDFAnnot->GetSubType();
61	if(cbSubType.Compare("3D") == 0)
62	{
63		FPDF_UnSupportError(FPDF_UNSP_ANNOT_3DANNOT);
64	}
65	else if(cbSubType.Compare("Screen") ==0)
66	{
67		CPDF_Dictionary* pAnnotDict = pPDFAnnot->m_pAnnotDict;
68		CFX_ByteString cbString;
69		if(pAnnotDict->KeyExist("IT"))
70			cbString = pAnnotDict->GetString("IT");
71		if(cbString.Compare("Img") != 0)
72			FPDF_UnSupportError(FPDF_UNSP_ANNOT_SCREEN_MEDIA);
73	}
74	else if(cbSubType.Compare("Movie") ==0)
75	{
76		FPDF_UnSupportError(FPDF_UNSP_ANNOT_MOVIE);
77	}
78	else if(cbSubType.Compare("Sound") ==0)
79	{
80		FPDF_UnSupportError(FPDF_UNSP_ANNOT_SOUND);
81	}
82	else if(cbSubType.Compare("RichMedia") ==0)
83	{
84		FPDF_UnSupportError(FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA);
85	}
86	else if(cbSubType.Compare("FileAttachment") ==0)
87	{
88		FPDF_UnSupportError(FPDF_UNSP_ANNOT_ATTACHMENT);
89	}
90	else if(cbSubType.Compare("Widget") ==0)
91	{
92		CPDF_Dictionary* pAnnotDict = pPDFAnnot->m_pAnnotDict;
93		CFX_ByteString cbString;
94		if(pAnnotDict->KeyExist("FT"))
95		{
96			cbString = pAnnotDict->GetString("FT");
97		}
98		if(cbString.Compare("Sig") == 0)
99		{
100			FPDF_UnSupportError(FPDF_UNSP_ANNOT_SIG);
101		}
102	}
103
104}
105
106FX_BOOL CheckSharedForm(CXML_Element * pElement, CFX_ByteString cbName)
107{
108	int count = pElement->CountAttrs();
109	int i=0;
110	for (i = 0; i < count; i++)
111	{
112		CFX_ByteString space, name;
113		CFX_WideString value;
114		pElement->GetAttrByIndex(i, space, name, value);
115		if (space == FX_BSTRC("xmlns") && name == FX_BSTRC("adhocwf") && value ==  L"http://ns.adobe.com/AcrobatAdhocWorkflow/1.0/")
116		{
117			CXML_Element *pVersion = pElement->GetElement("adhocwf",cbName);
118			if (!pVersion)
119				continue;
120			CFX_WideString wsContent = pVersion->GetContent(0); // == 1.1
121			int nType = wsContent.GetInteger();
122			switch(nType)
123			{
124			case 1:
125				FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_ACROBAT);
126				break;
127			case 2:
128				FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM);
129				break;
130			case 0:
131				FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_EMAIL);
132				break;
133			}
134		}
135	}
136
137	FX_DWORD nCount = pElement->CountChildren();
138	for(i=0; i<(int)nCount; i++)
139	{
140		CXML_Element::ChildType childType = pElement->GetChildType(i);
141		if(childType == CXML_Element::Element)
142		{
143			CXML_Element * pChild = pElement->GetElement(i);
144			if(CheckSharedForm(pChild, cbName))
145				return TRUE;
146		}
147	}
148	return FALSE;
149}
150
151void CheckUnSupportError(CPDF_Document * pDoc, FX_DWORD err_code)
152{
153	// Security
154	if(err_code == FPDF_ERR_SECURITY)
155	{
156		FPDF_UnSupportError(FPDF_UNSP_DOC_SECURITY);
157		return ;
158	}
159	if(!pDoc)
160		return ;
161
162	// Portfolios and Packages
163	CPDF_Dictionary * pRootDict = pDoc->GetRoot();
164	if(pRootDict)
165	{
166		CFX_ByteString cbString;
167		if(pRootDict->KeyExist("Collection"))
168		{
169			FPDF_UnSupportError(FPDF_UNSP_DOC_PORTABLECOLLECTION);
170			return ;
171		}
172		if(pRootDict->KeyExist("Names"))
173		{
174			CPDF_Dictionary* pNameDict = pRootDict->GetDict("Names");
175			if(pNameDict->KeyExist("EmbeddedFiles"))
176			{
177				FPDF_UnSupportError(FPDF_UNSP_DOC_ATTACHMENT);
178				return;
179			}
180			else if(pNameDict->KeyExist("JavaScript"))
181			{
182				CPDF_Dictionary* pJSDict = pNameDict->GetDict("JavaScript");
183				CPDF_Array * pArray = pJSDict->GetArray("Names");
184				if (pArray) {
185					int nCount = pArray->GetCount();
186					for(int i=0; i<nCount; i++)
187					{
188						CFX_ByteString cbStr = pArray->GetString(i);
189						if(cbStr.Compare("com.adobe.acrobat.SharedReview.Register") == 0)
190						{
191							FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDREVIEW);
192							return;
193						}
194					}
195				}
196			}
197		}
198	}
199
200	// SharedForm
201	CPDF_Metadata metaData;
202	metaData.LoadDoc(pDoc);
203	CXML_Element * pElement = metaData.GetRoot();
204	if(pElement)
205		CheckSharedForm(pElement, "workflowType");
206
207
208	// XFA Forms
209	CPDF_InterForm * pInterForm = FX_NEW CPDF_InterForm(pDoc,FALSE);
210	if (pInterForm)
211	{
212		if(pInterForm->HasXFAForm())
213		{
214			FPDF_UnSupportError(FPDF_UNSP_DOC_XFAFORM);
215		}
216		delete pInterForm;
217	}
218}
219
220DLLEXPORT int FPDFDoc_GetPageMode(FPDF_DOCUMENT document)
221{
222	if (!document) return PAGEMODE_UNKONOWN;
223	CPDF_Dictionary *pRoot = ((CPDF_Document*)document)->GetRoot();
224	if (!pRoot)
225		return PAGEMODE_UNKONOWN;
226	CPDF_Object* pName = pRoot->GetElement("PageMode");
227	if (!pName)
228		return PAGEMODE_USENONE;
229	CFX_ByteString strPageMode = pName->GetString();
230
231	if (strPageMode.IsEmpty()||strPageMode.EqualNoCase(FX_BSTR("UseNone")))
232		return PAGEMODE_USENONE;
233	else if (strPageMode.EqualNoCase(FX_BSTR("UseOutlines")))
234		return PAGEMODE_USEOUTLINES;
235	else if (strPageMode.EqualNoCase(FX_BSTR("UseThumbs")))
236		return PAGEMODE_USETHUMBS;
237	else if (strPageMode.EqualNoCase(FX_BSTR("FullScreen")))
238		return PAGEMODE_FULLSCREEN;
239	else if (strPageMode.EqualNoCase(FX_BSTR("UseOC")))
240		return PAGEMODE_USEOC;
241	else if (strPageMode.EqualNoCase(FX_BSTR("UseAttachments")))
242		return PAGEMODE_USEATTACHMENTS;
243
244	return PAGEMODE_UNKONOWN;
245}
246