1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
31 #include <rtl/ustring.hxx>
33 #include "saxhelper.hxx"
34 #include "libxml/parserInternals.h"
36 #ifndef XMLSEC_NO_XSLT
37 #include "libxslt/xslt.h"
40 namespace cssu
= com::sun::star::uno
;
41 namespace cssxs
= com::sun::star::xml::sax
;
42 namespace cssxcsax
= com::sun::star::xml::csax
;
45 * The return value is NULL terminated. The application has the responsibilty to
46 * deallocte the return value.
48 xmlChar
* ous_to_xmlstr( const rtl::OUString
& oustr
)
50 rtl::OString ostr
= rtl::OUStringToOString( oustr
, RTL_TEXTENCODING_UTF8
) ;
51 return xmlStrndup( ( xmlChar
* )ostr
.getStr(), ( int )ostr
.getLength() ) ;
55 * The return value is NULL terminated. The application has the responsibilty to
56 * deallocte the return value.
58 xmlChar
* ous_to_nxmlstr( const rtl::OUString
& oustr
, int& length
)
60 rtl::OString ostr
= rtl::OUStringToOString( oustr
, RTL_TEXTENCODING_UTF8
) ;
61 length
= ostr
.getLength();
63 return xmlStrndup( ( xmlChar
* )ostr
.getStr(), length
) ;
67 * The input parameter isn't necessaryly NULL terminated.
69 rtl::OUString
xmlchar_to_ous( const xmlChar
* pChar
, int length
)
73 return rtl::OUString( ( sal_Char
* )pChar
, length
, RTL_TEXTENCODING_UTF8
) ;
77 return rtl::OUString() ;
82 * The input parameter is NULL terminated
84 rtl::OUString
xmlstr_to_ous( const xmlChar
* pStr
)
88 return xmlchar_to_ous( pStr
, xmlStrlen( pStr
) ) ;
92 return rtl::OUString() ;
97 * The return value and the referenced value must be NULL terminated.
98 * The application has the responsibilty to deallocte the return value.
100 const xmlChar
** attrlist_to_nxmlstr( const cssu::Sequence
< cssxcsax::XMLAttribute
>& aAttributes
)
102 xmlChar
* attname
= NULL
;
103 xmlChar
* attvalue
= NULL
;
104 const xmlChar
** attrs
= NULL
;
105 rtl::OUString oustr
;
107 sal_Int32 nLength
= aAttributes
.getLength();;
111 attrs
= ( const xmlChar
** )xmlMalloc( ( nLength
* 2 + 2 ) * sizeof( xmlChar
* ) ) ;
118 for( int i
= 0 , j
= 0 ; j
< nLength
; ++j
)
120 attname
= ous_to_xmlstr( aAttributes
[j
].sName
) ;
121 attvalue
= ous_to_xmlstr( aAttributes
[j
].sValue
) ;
123 if( attname
!= NULL
&& attvalue
!= NULL
)
125 attrs
[i
++] = attname
;
126 attrs
[i
++] = attvalue
;
132 if( attname
!= NULL
)
134 if( attvalue
!= NULL
)
135 xmlFree( attvalue
) ;
145 * In this constructor, a libxml sax parser context is initialized. a libxml
146 * default sax handler is initialized with the context.
148 SAXHelper::SAXHelper( )
149 : m_pParserCtxt( NULL
),
150 m_pSaxHandler( NULL
)
153 LIBXML_TEST_VERSION
;
157 * xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS ;
159 xmlSubstituteEntitiesDefault( 1 ) ;
161 #ifndef XMLSEC_NO_XSLT
162 xmlIndentTreeOutput
= 1 ;
163 #endif /* XMLSEC_NO_XSLT */
165 m_pParserCtxt
= xmlNewParserCtxt() ;
170 * mmi : re-initialize the SAX handler to version 1
173 xmlSAXVersion(m_pParserCtxt
->sax
, 1);
177 if( m_pParserCtxt
->inputTab
[0] != NULL
)
179 m_pParserCtxt
->inputTab
[0] = NULL
;
182 if( m_pParserCtxt
== NULL
)
184 #ifndef XMLSEC_NO_XSLT
185 xsltCleanupGlobals() ;
187 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
188 // in other parts of the office.
189 // xmlCleanupParser() ;
190 throw cssu::RuntimeException() ;
192 else if( m_pParserCtxt
->sax
== NULL
)
194 xmlFreeParserCtxt( m_pParserCtxt
) ;
196 #ifndef XMLSEC_NO_XSLT
197 xsltCleanupGlobals() ;
199 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
200 // in other parts of the office.
201 // xmlCleanupParser() ;
202 m_pParserCtxt
= NULL
;
203 throw cssu::RuntimeException() ;
207 m_pSaxHandler
= m_pParserCtxt
->sax
;
210 m_pParserCtxt
->recovery
= 1 ;
217 * In this destructor, a libxml sax parser context is desturcted. The XML tree
218 * in the context is not deallocated because the tree is bind with a document
219 * model by the setTargetDocument method, which delegate the target document to
220 * destruct the xml tree.
222 SAXHelper::~SAXHelper() {
223 if( m_pParserCtxt
!= NULL
)
226 * In the situation that no object refer the Document, this destructor
227 * must deallocate the Document memory
229 if( m_pSaxHandler
== m_pParserCtxt
->sax
)
231 m_pSaxHandler
= NULL
;
234 xmlFreeParserCtxt( m_pParserCtxt
) ;
235 m_pParserCtxt
= NULL
;
238 if( m_pSaxHandler
!= NULL
)
240 xmlFree( m_pSaxHandler
) ;
241 m_pSaxHandler
= NULL
;
243 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
244 // in other parts of the office.
245 // xmlCleanupParser() ;
248 xmlNodePtr
SAXHelper::getCurrentNode()
250 return m_pParserCtxt
->node
;
253 void SAXHelper::setCurrentNode(const xmlNodePtr pNode
)
256 * This is really a black trick.
257 * When the current node is replaced, the nodeTab
258 * stack's top has to been replaced with the same
259 * node, in order to make compatibility.
261 m_pParserCtxt
->nodeTab
[m_pParserCtxt
->nodeNr
- 1]
262 = m_pParserCtxt
->node
266 xmlDocPtr
SAXHelper::getDocument()
268 return m_pParserCtxt
->myDoc
;
272 * XDocumentHandler -- start an xml document
274 void SAXHelper::startDocument( void )
275 throw( cssxs::SAXException
, cssu::RuntimeException
)
280 xmlParserInputPtr pInput
= xmlNewInputStream( m_pParserCtxt
) ;
282 if( m_pParserCtxt
->inputTab
!= NULL
&& m_pParserCtxt
->inputMax
!= 0 )
284 m_pParserCtxt
->inputTab
[0] = pInput
;
285 m_pParserCtxt
->input
= pInput
;
288 m_pSaxHandler
->startDocument( m_pParserCtxt
) ;
290 if( m_pParserCtxt
== NULL
|| m_pParserCtxt
->myDoc
== NULL
)
292 throw cssu::RuntimeException() ;
297 * XDocumentHandler -- end an xml document
299 void SAXHelper::endDocument( void )
300 throw( cssxs::SAXException
, cssu::RuntimeException
)
302 m_pSaxHandler
->endDocument( m_pParserCtxt
) ;
306 * XDocumentHandler -- start an xml element
308 void SAXHelper::startElement(
309 const rtl::OUString
& aName
,
310 const cssu::Sequence
< cssxcsax::XMLAttribute
>& aAttributes
)
311 throw( cssxs::SAXException
, cssu::RuntimeException
)
313 const xmlChar
* fullName
= NULL
;
314 const xmlChar
** attrs
= NULL
;
316 fullName
= ous_to_xmlstr( aName
) ;
317 attrs
= attrlist_to_nxmlstr( aAttributes
) ;
319 if( fullName
!= NULL
|| attrs
!= NULL
)
321 m_pSaxHandler
->startElement( m_pParserCtxt
, fullName
, attrs
) ;
324 if( fullName
!= NULL
)
326 xmlFree( ( xmlChar
* )fullName
) ;
332 for( int i
= 0 ; attrs
[i
] != NULL
; ++i
)
334 xmlFree( ( xmlChar
* )attrs
[i
] ) ;
338 xmlFree( ( void* ) attrs
) ;
344 * XDocumentHandler -- end an xml element
346 void SAXHelper::endElement( const rtl::OUString
& aName
)
347 throw( cssxs::SAXException
, cssu::RuntimeException
)
349 xmlChar
* fullname
= NULL
;
351 fullname
= ous_to_xmlstr( aName
) ;
352 m_pSaxHandler
->endElement( m_pParserCtxt
, fullname
) ;
354 if( fullname
!= NULL
)
356 xmlFree( ( xmlChar
* )fullname
) ;
362 * XDocumentHandler -- an xml element or cdata characters
364 void SAXHelper::characters( const rtl::OUString
& aChars
)
365 throw( cssxs::SAXException
, cssu::RuntimeException
)
367 const xmlChar
* chars
= NULL
;
370 chars
= ous_to_nxmlstr( aChars
, length
) ;
371 m_pSaxHandler
->characters( m_pParserCtxt
, chars
, length
) ;
375 xmlFree( ( xmlChar
* )chars
) ;
380 * XDocumentHandler -- ignorable xml white space
382 void SAXHelper::ignorableWhitespace( const rtl::OUString
& aWhitespaces
)
383 throw( cssxs::SAXException
, cssu::RuntimeException
)
385 const xmlChar
* chars
= NULL
;
388 chars
= ous_to_nxmlstr( aWhitespaces
, length
) ;
389 m_pSaxHandler
->ignorableWhitespace( m_pParserCtxt
, chars
, length
) ;
393 xmlFree( ( xmlChar
* )chars
) ;
398 * XDocumentHandler -- preaorocessing instruction
400 void SAXHelper::processingInstruction(
401 const rtl::OUString
& aTarget
,
402 const rtl::OUString
& aData
)
403 throw( cssxs::SAXException
, cssu::RuntimeException
)
405 xmlChar
* target
= NULL
;
406 xmlChar
* data
= NULL
;
408 target
= ous_to_xmlstr( aTarget
) ;
409 data
= ous_to_xmlstr( aData
) ;
411 m_pSaxHandler
->processingInstruction( m_pParserCtxt
, target
, data
) ;
415 xmlFree( ( xmlChar
* )target
) ;
421 xmlFree( ( xmlChar
* )data
) ;
427 * XDocumentHandler -- set document locator
428 * In this case, locator is useless.
430 void SAXHelper::setDocumentLocator(
431 const cssu::Reference
< cssxs::XLocator
> &)
432 throw( cssxs::SAXException
, cssu::RuntimeException
)
434 //--Pseudo code if necessary
435 //--m_pSaxLocator is a member defined as xmlSAXHabdlerPtr
436 //--m_pSaxLocatorHdl is a member defined as Sax_Locator
438 //if( m_pSaxLocator != NULL ) {
439 // //Deallocate the memory
441 //if( m_pSaxLocatorHdl != NULL ) {
442 // //Deallocate the memory
445 //m_pSaxLocatorHdl = new Sax_Locator( xLocator ) ;
446 //m_pSaxLocator = { m_pSaxLocatorHdl->getPublicId , m_pSaxLocatorHdl->getSystemId , m_pSaxLocatorHdl->getLineNumber , m_pSaxLocatorHdl->getColumnNumber } ;
448 //m_pSaxHandler->setDocumentLocator( m_pParserCtxt , m_pSaxLocator ) ;