Bump version to 6.0-36
[LibreOffice.git] / xmlsecurity / source / xmlsec / saxhelper.cxx
blob52d62b120bec9519c1a304162375fd09876d9796
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <rtl/ustring.hxx>
23 #include <xmlsec/saxhelper.hxx>
24 #include <libxml/parserInternals.h>
26 #ifndef XMLSEC_NO_XSLT
27 #include "libxslt/xslt.h"
28 #endif
30 namespace cssu = com::sun::star::uno;
31 namespace cssxs = com::sun::star::xml::sax;
32 namespace cssxcsax = com::sun::star::xml::csax;
34 /**
35 * The return value is NULL terminated. The application has the responsibilty to
36 * deallocte the return value.
38 xmlChar* ous_to_xmlstr( const OUString& oustr )
40 OString ostr = OUStringToOString( oustr , RTL_TEXTENCODING_UTF8 ) ;
41 return xmlStrndup( reinterpret_cast<xmlChar const *>(ostr.getStr()), ( int )ostr.getLength() ) ;
44 /**
45 * The return value is NULL terminated. The application has the responsibilty to
46 * deallocte the return value.
48 xmlChar* ous_to_nxmlstr( const OUString& oustr, int& length )
50 OString ostr = OUStringToOString( oustr , RTL_TEXTENCODING_UTF8 ) ;
51 length = ostr.getLength();
53 return xmlStrndup( reinterpret_cast<xmlChar const *>(ostr.getStr()), length ) ;
56 /**
57 * The return value and the referenced value must be NULL terminated.
58 * The application has the responsibilty to deallocte the return value.
60 const xmlChar** attrlist_to_nxmlstr( const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
62 xmlChar* attname = nullptr ;
63 xmlChar* attvalue = nullptr ;
64 const xmlChar** attrs = nullptr ;
66 sal_Int32 nLength = aAttributes.getLength();
68 if( nLength != 0 )
70 attrs = static_cast<const xmlChar**>(xmlMalloc( ( nLength * 2 + 2 ) * sizeof( xmlChar* ) ));
72 else
74 return nullptr ;
77 for( int i = 0 , j = 0 ; j < nLength ; ++j )
79 attname = ous_to_xmlstr( aAttributes[j].sName ) ;
80 attvalue = ous_to_xmlstr( aAttributes[j].sValue ) ;
82 if( attname != nullptr && attvalue != nullptr )
84 attrs[i++] = attname ;
85 attrs[i++] = attvalue ;
86 attrs[i] = nullptr ;
87 attrs[i+1] = nullptr ;
89 else
91 if( attname != nullptr )
92 xmlFree( attname ) ;
93 if( attvalue != nullptr )
94 xmlFree( attvalue ) ;
98 return attrs ;
102 * Constructor
104 * In this constructor, a libxml sax parser context is initialized. a libxml
105 * default sax handler is initialized with the context.
107 SAXHelper::SAXHelper( )
108 : m_pParserCtxt( nullptr ),
109 m_pSaxHandler( nullptr )
111 xmlInitParser() ;
112 LIBXML_TEST_VERSION ;
115 * compile error:
116 * xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS ;
118 xmlSubstituteEntitiesDefault( 1 ) ;
120 #ifndef XMLSEC_NO_XSLT
121 xmlIndentTreeOutput = 1 ;
122 #endif /* XMLSEC_NO_XSLT */
124 m_pParserCtxt = xmlNewParserCtxt() ;
126 if( m_pParserCtxt == nullptr )
128 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
129 // in other parts of the office.
130 // xmlCleanupParser() ;
131 // and neither can we call xsltCleanupGlobals()
132 throw cssu::RuntimeException() ;
135 xmlSAXVersion(m_pParserCtxt->sax, 1);
137 if (m_pParserCtxt->inputTab != nullptr)
139 m_pParserCtxt->inputTab[0] = nullptr ;
142 if( m_pParserCtxt->sax == nullptr )
144 xmlFreeParserCtxt( m_pParserCtxt ) ;
146 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
147 // in other parts of the office.
148 // xmlCleanupParser() ;
149 // and neither can we call xsltCleanupGlobals()
150 m_pParserCtxt = nullptr ;
151 throw cssu::RuntimeException() ;
153 else
155 m_pSaxHandler = m_pParserCtxt->sax ;
157 //Adjust the context
158 m_pParserCtxt->recovery = 1 ;
163 * Destructor
165 * In this destructor, a libxml sax parser context is destructed. The XML tree
166 * in the context is not deallocated because the tree is bind with a document
167 * model by the setTargetDocument method, which delegate the target document to
168 * destruct the xml tree.
170 SAXHelper::~SAXHelper() {
171 if( m_pParserCtxt != nullptr )
174 * In the situation that no object refer the Document, this destructor
175 * must deallocate the Document memory
177 if( m_pSaxHandler == m_pParserCtxt->sax )
179 m_pSaxHandler = nullptr ;
182 xmlFreeParserCtxt( m_pParserCtxt ) ;
183 m_pParserCtxt = nullptr ;
186 if( m_pSaxHandler != nullptr )
188 xmlFree( m_pSaxHandler ) ;
189 m_pSaxHandler = nullptr ;
191 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
192 // in other parts of the office.
193 // xmlCleanupParser() ;
197 void SAXHelper::setCurrentNode(const xmlNodePtr pNode)
200 * This is really a black trick.
201 * When the current node is replaced, the nodeTab
202 * stack's top has to been replaced with the same
203 * node, in order to make compatibility.
205 m_pParserCtxt->nodeTab[m_pParserCtxt->nodeNr - 1]
206 = m_pParserCtxt->node
207 = pNode;
212 * XDocumentHandler -- start an xml document
214 void SAXHelper::startDocument()
216 if( m_pParserCtxt == nullptr)
218 throw cssu::RuntimeException() ;
221 * Adjust inputTab
223 xmlParserInputPtr pInput = xmlNewInputStream( m_pParserCtxt ) ;
225 if( m_pParserCtxt->inputTab != nullptr && m_pParserCtxt->inputMax != 0 )
227 m_pParserCtxt->inputTab[0] = pInput ;
228 m_pParserCtxt->input = pInput ;
231 m_pSaxHandler->startDocument( m_pParserCtxt ) ;
233 if( m_pParserCtxt->myDoc == nullptr )
235 throw cssu::RuntimeException() ;
240 * XDocumentHandler -- end an xml document
242 void SAXHelper::endDocument()
244 m_pSaxHandler->endDocument( m_pParserCtxt ) ;
248 * XDocumentHandler -- start an xml element
250 void SAXHelper::startElement(
251 const OUString& aName,
252 const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
254 const xmlChar* fullName = nullptr ;
255 const xmlChar** attrs = nullptr ;
257 fullName = ous_to_xmlstr( aName ) ;
258 attrs = attrlist_to_nxmlstr( aAttributes ) ;
260 if( fullName != nullptr || attrs != nullptr )
262 m_pSaxHandler->startElement( m_pParserCtxt , fullName , attrs ) ;
265 if( fullName != nullptr )
267 xmlFree( const_cast<xmlChar*>(fullName) ) ;
268 fullName = nullptr ;
271 if( attrs != nullptr )
273 for( int i = 0 ; attrs[i] != nullptr ; ++i )
275 xmlFree( const_cast<xmlChar*>(attrs[i]) ) ;
276 attrs[i] = nullptr ;
279 xmlFree( static_cast<void*>(attrs) ) ;
280 attrs = nullptr ;
285 * XDocumentHandler -- end an xml element
287 void SAXHelper::endElement( const OUString& aName )
289 xmlChar* fullname = nullptr ;
291 fullname = ous_to_xmlstr( aName ) ;
292 m_pSaxHandler->endElement( m_pParserCtxt , fullname ) ;
294 if( fullname != nullptr )
296 xmlFree( fullname ) ;
297 fullname = nullptr ;
302 * XDocumentHandler -- an xml element or cdata characters
304 void SAXHelper::characters( const OUString& aChars )
306 const xmlChar* chars = nullptr ;
307 int length = 0 ;
309 chars = ous_to_nxmlstr( aChars, length ) ;
310 m_pSaxHandler->characters( m_pParserCtxt , chars , length ) ;
312 if( chars != nullptr )
314 xmlFree( const_cast<xmlChar*>(chars) ) ;
319 * XDocumentHandler -- ignorable xml white space
321 void SAXHelper::ignorableWhitespace( const OUString& aWhitespaces )
323 const xmlChar* chars = nullptr ;
324 int length = 0 ;
326 chars = ous_to_nxmlstr( aWhitespaces, length ) ;
327 m_pSaxHandler->ignorableWhitespace( m_pParserCtxt , chars , length ) ;
329 if( chars != nullptr )
331 xmlFree( const_cast<xmlChar*>(chars) ) ;
336 * XDocumentHandler -- preprocessing instruction
338 void SAXHelper::processingInstruction(
339 const OUString& aTarget,
340 const OUString& aData )
342 xmlChar* target = nullptr ;
343 xmlChar* data = nullptr ;
345 target = ous_to_xmlstr( aTarget ) ;
346 data = ous_to_xmlstr( aData ) ;
348 m_pSaxHandler->processingInstruction( m_pParserCtxt , target , data ) ;
350 if( target != nullptr )
352 xmlFree( target ) ;
353 target = nullptr ;
356 if( data != nullptr )
358 xmlFree( data ) ;
359 data = nullptr ;
363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */