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