From 830cc95abb7911f5f6f0ba8c71ef46f3ca8ef383 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Wed, 5 Jun 2013 16:50:50 +0200 Subject: sax: FastSaxSerializer: add well-formedness assertions In an --enable-dbgutil build, assert on the following XML well-formedness violations: * Element Type Match (-> start/end tag mismatch) * Unique Att Spec (-> duplicate attributes) Change-Id: I1d5c405b4316ba941be1db7df6cacf00b5837261 --- sax/source/tools/fastserializer.cxx | 50 ++++++++++++++++++++++++++++++++++++- sax/source/tools/fastserializer.hxx | 5 ++++ 2 files changed, 54 insertions(+), 1 deletion(-) (limited to 'sax/source') diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx index eba4548ee6c5..a9b73ae3d284 100644 --- a/sax/source/tools/fastserializer.cxx +++ b/sax/source/tools/fastserializer.cxx @@ -30,6 +30,7 @@ #if OSL_DEBUG_LEVEL > 0 #include +#include #endif using ::comphelper::SequenceAsVector; @@ -123,6 +124,25 @@ namespace sax_fastparser { writeBytes(mxFastTokenHandler->getUTF8Identifier(nElement)); } +#ifdef DBG_UTIL + OString SAL_CALL FastSaxSerializer::getId( ::sal_Int32 nElement ) + { + if (HAS_NAMESPACE(nElement)) { + Sequence const ns( + mxFastTokenHandler->getUTF8Identifier(NAMESPACE(nElement))); + Sequence const name( + mxFastTokenHandler->getUTF8Identifier(TOKEN(nElement))); + return OString(reinterpret_cast(ns.getConstArray()), ns.getLength()) + + OString(reinterpret_cast(maColon.getConstArray()), maColon.getLength()) + + OString(reinterpret_cast(name.getConstArray()), name.getLength()); + } else { + Sequence const name( + mxFastTokenHandler->getUTF8Identifier(nElement)); + return OString(reinterpret_cast(name.getConstArray()), name.getLength()); + } + } +#endif + void SAL_CALL FastSaxSerializer::startFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException) { @@ -132,6 +152,10 @@ namespace sax_fastparser { if ( !maMarkStack.empty() ) maMarkStack.top()->setCurrentElement( Element ); +#ifdef DBG_UTIL + m_DebugStartedElements.push(Element); +#endif + writeBytes(toUnoSequence(maOpeningBracket)); writeId(Element); @@ -146,6 +170,13 @@ namespace sax_fastparser { if (!mxOutputStream.is()) return; +#ifdef DBG_UTIL + assert(!m_DebugStartedElements.empty()); + // Well-formedness constraint: Element Type Match + assert(Element == m_DebugStartedElements.top()); + m_DebugStartedElements.pop(); +#endif + writeBytes(toUnoSequence(maOpeningBracketAndSlash)); writeId(Element); @@ -193,6 +224,9 @@ namespace sax_fastparser { } void FastSaxSerializer::writeFastAttributeList( const Reference< XFastAttributeList >& Attribs ) { +#ifdef DBG_UTIL + ::std::set DebugAttributes; +#endif Sequence< Attribute > aAttrSeq = Attribs->getUnknownAttributes(); const Attribute *pAttr = aAttrSeq.getConstArray(); sal_Int32 nAttrLength = aAttrSeq.getLength(); @@ -200,7 +234,13 @@ namespace sax_fastparser { { writeBytes(toUnoSequence(maSpace)); - write(pAttr[i].Name); + OUString const& rAttrName(pAttr[i].Name); +#ifdef DBG_UTIL + // Well-formedness constraint: Unique Att Spec + assert(DebugAttributes.find(rAttrName) == DebugAttributes.end()); + DebugAttributes.insert(rAttrName); +#endif + write(rAttrName); writeBytes(toUnoSequence(maEqualSignAndQuote)); write(escapeXml(pAttr[i].Value)); writeBytes(toUnoSequence(maQuote)); @@ -216,6 +256,14 @@ namespace sax_fastparser { sal_Int32 nToken = pFastAttr[j].Token; writeId(nToken); +#ifdef DBG_UTIL + // Well-formedness constraint: Unique Att Spec + OUString const name(OStringToOUString(getId(nToken), + RTL_TEXTENCODING_UTF8)); + assert(DebugAttributes.find(name) == DebugAttributes.end()); + DebugAttributes.insert(name); +#endif + writeBytes(toUnoSequence(maEqualSignAndQuote)); write(escapeXml(Attribs->getValue(pFastAttr[j].Token))); diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx index 38c8e89f4e59..95ebb1407ec1 100644 --- a/sax/source/tools/fastserializer.hxx +++ b/sax/source/tools/fastserializer.hxx @@ -111,6 +111,7 @@ public: // C++ helpers void SAL_CALL writeId( ::sal_Int32 Element ); + OString SAL_CALL getId( ::sal_Int32 Element ); static OUString escapeXml( const OUString& s ); @@ -207,6 +208,10 @@ private: ::std::stack< boost::shared_ptr< ForMerge > > maMarkStack; ::std::stack< boost::shared_ptr< ForMerge > > maSavedMarkStack; +#ifdef DBG_UTIL + ::std::stack m_DebugStartedElements; +#endif + void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ); void write( const OUString& s ); -- cgit