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 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 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 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 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 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 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