Bump version to 5.0-14
[LibreOffice.git] / xmlsecurity / source / xmlsec / saxhelper.cxx
blobf281dfda8112449a80369970e3c99c8e60603956
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 "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 = NULL ;
63 xmlChar* attvalue = NULL ;
64 const xmlChar** attrs = NULL ;
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 NULL ;
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 != NULL && attvalue != NULL )
84 attrs[i++] = attname ;
85 attrs[i++] = attvalue ;
86 attrs[i] = NULL ;
87 attrs[i+1] = NULL ;
89 else
91 if( attname != NULL )
92 xmlFree( attname ) ;
93 if( attvalue != NULL )
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( NULL ),
109 m_pSaxHandler( NULL )
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 == NULL )
128 #ifndef XMLSEC_NO_XSLT
129 xsltCleanupGlobals() ;
130 #endif
131 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
132 // in other parts of the office.
133 // xmlCleanupParser() ;
134 throw cssu::RuntimeException() ;
136 else
138 xmlSAXVersion(m_pParserCtxt->sax, 1);
140 if (m_pParserCtxt->inputTab != nullptr)
142 m_pParserCtxt->inputTab[0] = NULL ;
145 if( m_pParserCtxt->sax == NULL )
147 xmlFreeParserCtxt( m_pParserCtxt ) ;
149 #ifndef XMLSEC_NO_XSLT
150 xsltCleanupGlobals() ;
151 #endif
152 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
153 // in other parts of the office.
154 // xmlCleanupParser() ;
155 m_pParserCtxt = NULL ;
156 throw cssu::RuntimeException() ;
158 else
160 m_pSaxHandler = m_pParserCtxt->sax ;
162 //Adjust the context
163 m_pParserCtxt->recovery = 1 ;
169 * Destructor
171 * In this destructor, a libxml sax parser context is desturcted. The XML tree
172 * in the context is not deallocated because the tree is bind with a document
173 * model by the setTargetDocument method, which delegate the target document to
174 * destruct the xml tree.
176 SAXHelper::~SAXHelper() {
177 if( m_pParserCtxt != NULL )
180 * In the situation that no object refer the Document, this destructor
181 * must deallocate the Document memory
183 if( m_pSaxHandler == m_pParserCtxt->sax )
185 m_pSaxHandler = NULL ;
188 xmlFreeParserCtxt( m_pParserCtxt ) ;
189 m_pParserCtxt = NULL ;
192 if( m_pSaxHandler != NULL )
194 xmlFree( m_pSaxHandler ) ;
195 m_pSaxHandler = NULL ;
197 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
198 // in other parts of the office.
199 // xmlCleanupParser() ;
203 void SAXHelper::setCurrentNode(const xmlNodePtr pNode)
206 * This is really a black trick.
207 * When the current node is replaced, the nodeTab
208 * stack's top has to been replaced with the same
209 * node, in order to make compatibility.
211 m_pParserCtxt->nodeTab[m_pParserCtxt->nodeNr - 1]
212 = m_pParserCtxt->node
213 = pNode;
218 * XDocumentHandler -- start an xml document
220 void SAXHelper::startDocument()
221 throw( cssxs::SAXException , cssu::RuntimeException )
223 if( m_pParserCtxt == NULL)
225 throw cssu::RuntimeException() ;
228 * Adjust inputTab
230 xmlParserInputPtr pInput = xmlNewInputStream( m_pParserCtxt ) ;
232 if( m_pParserCtxt->inputTab != NULL && m_pParserCtxt->inputMax != 0 )
234 m_pParserCtxt->inputTab[0] = pInput ;
235 m_pParserCtxt->input = pInput ;
238 m_pSaxHandler->startDocument( m_pParserCtxt ) ;
240 if( m_pParserCtxt->myDoc == NULL )
242 throw cssu::RuntimeException() ;
247 * XDocumentHandler -- end an xml document
249 void SAXHelper::endDocument()
250 throw( cssxs::SAXException , cssu::RuntimeException )
252 m_pSaxHandler->endDocument( m_pParserCtxt ) ;
256 * XDocumentHandler -- start an xml element
258 void SAXHelper::startElement(
259 const OUString& aName,
260 const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
261 throw( cssxs::SAXException , cssu::RuntimeException )
263 const xmlChar* fullName = NULL ;
264 const xmlChar** attrs = NULL ;
266 fullName = ous_to_xmlstr( aName ) ;
267 attrs = attrlist_to_nxmlstr( aAttributes ) ;
269 if( fullName != NULL || attrs != NULL )
271 m_pSaxHandler->startElement( m_pParserCtxt , fullName , attrs ) ;
274 if( fullName != NULL )
276 xmlFree( const_cast<xmlChar*>(fullName) ) ;
277 fullName = NULL ;
280 if( attrs != NULL )
282 for( int i = 0 ; attrs[i] != NULL ; ++i )
284 xmlFree( const_cast<xmlChar*>(attrs[i]) ) ;
285 attrs[i] = NULL ;
288 xmlFree( ( void* ) attrs ) ;
289 attrs = NULL ;
294 * XDocumentHandler -- end an xml element
296 void SAXHelper::endElement( const OUString& aName )
297 throw( cssxs::SAXException , cssu::RuntimeException )
299 xmlChar* fullname = NULL ;
301 fullname = ous_to_xmlstr( aName ) ;
302 m_pSaxHandler->endElement( m_pParserCtxt , fullname ) ;
304 if( fullname != NULL )
306 xmlFree( fullname ) ;
307 fullname = NULL ;
312 * XDocumentHandler -- an xml element or cdata characters
314 void SAXHelper::characters( const OUString& aChars )
315 throw( cssxs::SAXException , cssu::RuntimeException )
317 const xmlChar* chars = NULL ;
318 int length = 0 ;
320 chars = ous_to_nxmlstr( aChars, length ) ;
321 m_pSaxHandler->characters( m_pParserCtxt , chars , length ) ;
323 if( chars != NULL )
325 xmlFree( const_cast<xmlChar*>(chars) ) ;
330 * XDocumentHandler -- ignorable xml white space
332 void SAXHelper::ignorableWhitespace( const OUString& aWhitespaces )
333 throw( cssxs::SAXException , cssu::RuntimeException )
335 const xmlChar* chars = NULL ;
336 int length = 0 ;
338 chars = ous_to_nxmlstr( aWhitespaces, length ) ;
339 m_pSaxHandler->ignorableWhitespace( m_pParserCtxt , chars , length ) ;
341 if( chars != NULL )
343 xmlFree( const_cast<xmlChar*>(chars) ) ;
348 * XDocumentHandler -- preaorocessing instruction
350 void SAXHelper::processingInstruction(
351 const OUString& aTarget,
352 const OUString& aData )
353 throw( cssxs::SAXException , cssu::RuntimeException )
355 xmlChar* target = NULL ;
356 xmlChar* data = NULL ;
358 target = ous_to_xmlstr( aTarget ) ;
359 data = ous_to_xmlstr( aData ) ;
361 m_pSaxHandler->processingInstruction( m_pParserCtxt , target , data ) ;
363 if( target != NULL )
365 xmlFree( target ) ;
366 target = NULL ;
369 if( data != NULL )
371 xmlFree( data ) ;
372 data = NULL ;
376 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */