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