Home | History | Annotate | Download | only in fpdfsdk
      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