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