1 // Copyright 2016 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 "core/fpdfdoc/cpdf_metadata.h" 8 9 #include <memory> 10 11 #include "core/fpdfapi/parser/cpdf_stream.h" 12 #include "core/fpdfapi/parser/cpdf_stream_acc.h" 13 #include "core/fxcrt/cfx_readonlymemorystream.h" 14 #include "core/fxcrt/fx_codepage.h" 15 #include "core/fxcrt/xml/cfx_xmldocument.h" 16 #include "core/fxcrt/xml/cfx_xmlelement.h" 17 #include "core/fxcrt/xml/cfx_xmlparser.h" 18 19 namespace { 20 CheckForSharedFormInternal(CFX_XMLElement * element,std::vector<UnsupportedFeature> * unsupported)21void CheckForSharedFormInternal(CFX_XMLElement* element, 22 std::vector<UnsupportedFeature>* unsupported) { 23 WideString attr = 24 element->GetAttribute(WideString::FromASCII("xmlns:adhocwf")); 25 if (attr.EqualsASCII("http://ns.adobe.com/AcrobatAdhocWorkflow/1.0/")) { 26 for (const auto* child = element->GetFirstChild(); child; 27 child = child->GetNextSibling()) { 28 if (child->GetType() != CFX_XMLNode::Type::kElement) 29 continue; 30 31 const auto* child_elem = static_cast<const CFX_XMLElement*>(child); 32 if (!child_elem->GetName().EqualsASCII("adhocwf:workflowType")) 33 continue; 34 35 switch (child_elem->GetTextData().GetInteger()) { 36 case 0: 37 unsupported->push_back(UnsupportedFeature::kDocumentSharedFormEmail); 38 break; 39 case 1: 40 unsupported->push_back( 41 UnsupportedFeature::kDocumentSharedFormAcrobat); 42 break; 43 case 2: 44 unsupported->push_back( 45 UnsupportedFeature::kDocumentSharedFormFilesystem); 46 break; 47 } 48 // We only care about the first one we find. 49 break; 50 } 51 } 52 53 for (auto* child = element->GetFirstChild(); child; 54 child = child->GetNextSibling()) { 55 CFX_XMLElement* pElement = ToXMLElement(child); 56 if (pElement) 57 CheckForSharedFormInternal(pElement, unsupported); 58 } 59 } 60 61 } // namespace 62 CPDF_Metadata(const CPDF_Stream * pStream)63CPDF_Metadata::CPDF_Metadata(const CPDF_Stream* pStream) : stream_(pStream) { 64 ASSERT(pStream); 65 } 66 67 CPDF_Metadata::~CPDF_Metadata() = default; 68 CheckForSharedForm() const69std::vector<UnsupportedFeature> CPDF_Metadata::CheckForSharedForm() const { 70 auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(stream_.Get()); 71 pAcc->LoadAllDataFiltered(); 72 73 auto stream = pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(pAcc->GetSpan()); 74 CFX_XMLParser parser(stream); 75 std::unique_ptr<CFX_XMLDocument> doc = parser.Parse(); 76 if (!doc) 77 return {}; 78 79 std::vector<UnsupportedFeature> unsupported; 80 CheckForSharedFormInternal(doc->GetRoot(), &unsupported); 81 return unsupported; 82 } 83