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_basic.h"
     18 #include "core/fxcrt/fx_memory.h"
     19 #include "core/fxcrt/fx_xml.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 DLLEXPORT FPDF_BOOL STDCALL
     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     CFX_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     CFX_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, CFX_ByteString cbName) {
     79   int count = pElement->CountAttrs();
     80   int i = 0;
     81   for (i = 0; i < count; i++) {
     82     CFX_ByteString space, name;
     83     CFX_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.AsStringC());
     89       if (!pVersion)
     90         continue;
     91       CFX_WideString wsContent = pVersion->GetContent(0);
     92       int nType = wsContent.GetInteger();
     93       switch (nType) {
     94         case 1:
     95           FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_ACROBAT);
     96           break;
     97         case 2:
     98           FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM);
     99           break;
    100         case 0:
    101           FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_EMAIL);
    102           break;
    103       }
    104     }
    105   }
    106 
    107   uint32_t nCount = pElement->CountChildren();
    108   for (i = 0; i < (int)nCount; i++) {
    109     CXML_Element::ChildType childType = pElement->GetChildType(i);
    110     if (childType == CXML_Element::Element) {
    111       CXML_Element* pChild = pElement->GetElement(i);
    112       if (CheckSharedForm(pChild, cbName))
    113         return true;
    114     }
    115   }
    116   return false;
    117 }
    118 
    119 void CheckUnSupportError(CPDF_Document* pDoc, uint32_t err_code) {
    120   // Security
    121   if (err_code == FPDF_ERR_SECURITY) {
    122     FPDF_UnSupportError(FPDF_UNSP_DOC_SECURITY);
    123     return;
    124   }
    125   if (!pDoc)
    126     return;
    127 
    128   // Portfolios and Packages
    129   CPDF_Dictionary* pRootDict = pDoc->GetRoot();
    130   if (pRootDict) {
    131     CFX_ByteString cbString;
    132     if (pRootDict->KeyExist("Collection")) {
    133       FPDF_UnSupportError(FPDF_UNSP_DOC_PORTABLECOLLECTION);
    134       return;
    135     }
    136     if (pRootDict->KeyExist("Names")) {
    137       CPDF_Dictionary* pNameDict = pRootDict->GetDictFor("Names");
    138       if (pNameDict && pNameDict->KeyExist("EmbeddedFiles")) {
    139         FPDF_UnSupportError(FPDF_UNSP_DOC_ATTACHMENT);
    140         return;
    141       }
    142       if (pNameDict && pNameDict->KeyExist("JavaScript")) {
    143         CPDF_Dictionary* pJSDict = pNameDict->GetDictFor("JavaScript");
    144         CPDF_Array* pArray = pJSDict ? pJSDict->GetArrayFor("Names") : nullptr;
    145         if (pArray) {
    146           for (size_t i = 0; i < pArray->GetCount(); i++) {
    147             CFX_ByteString cbStr = pArray->GetStringAt(i);
    148             if (cbStr.Compare("com.adobe.acrobat.SharedReview.Register") == 0) {
    149               FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDREVIEW);
    150               return;
    151             }
    152           }
    153         }
    154       }
    155     }
    156   }
    157 
    158   // SharedForm
    159   CPDF_Metadata metaData(pDoc);
    160   const CXML_Element* pElement = metaData.GetRoot();
    161   if (pElement)
    162     CheckSharedForm(pElement, "workflowType");
    163 
    164 #ifndef PDF_ENABLE_XFA
    165   // XFA Forms
    166   CPDF_InterForm interform(pDoc);
    167   if (interform.HasXFAForm())
    168     FPDF_UnSupportError(FPDF_UNSP_DOC_XFAFORM);
    169 #endif  // PDF_ENABLE_XFA
    170 }
    171 
    172 DLLEXPORT int STDCALL FPDFDoc_GetPageMode(FPDF_DOCUMENT document) {
    173   CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
    174   if (!pDoc)
    175     return PAGEMODE_UNKNOWN;
    176 
    177   CPDF_Dictionary* pRoot = pDoc->GetRoot();
    178   if (!pRoot)
    179     return PAGEMODE_UNKNOWN;
    180 
    181   CPDF_Object* pName = pRoot->GetObjectFor("PageMode");
    182   if (!pName)
    183     return PAGEMODE_USENONE;
    184 
    185   CFX_ByteString strPageMode = pName->GetString();
    186   if (strPageMode.IsEmpty() || strPageMode.EqualNoCase("UseNone"))
    187     return PAGEMODE_USENONE;
    188   if (strPageMode.EqualNoCase("UseOutlines"))
    189     return PAGEMODE_USEOUTLINES;
    190   if (strPageMode.EqualNoCase("UseThumbs"))
    191     return PAGEMODE_USETHUMBS;
    192   if (strPageMode.EqualNoCase("FullScreen"))
    193     return PAGEMODE_FULLSCREEN;
    194   if (strPageMode.EqualNoCase("UseOC"))
    195     return PAGEMODE_USEOC;
    196   if (strPageMode.EqualNoCase("UseAttachments"))
    197     return PAGEMODE_USEATTACHMENTS;
    198 
    199   return PAGEMODE_UNKNOWN;
    200 }
    201