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