[Libreoffice-commits] core.git: 3 commits - sax/source sc/source
Michael Stahl
mstahl at redhat.com
Wed Jun 5 07:58:18 PDT 2013
sax/source/expatwrap/saxwriter.cxx | 34 +++++++++++++++++++++++-
sax/source/tools/fastserializer.cxx | 50 +++++++++++++++++++++++++++++++++++-
sax/source/tools/fastserializer.hxx | 5 +++
sc/source/filter/excel/xepage.cxx | 17 +++++++++---
sc/source/filter/excel/xerecord.cxx | 27 +++++++------------
sc/source/filter/inc/xerecord.hxx | 17 +++++-------
sc/source/filter/inc/xestream.hxx | 1
7 files changed, 118 insertions(+), 33 deletions(-)
New commits:
commit 830cc95abb7911f5f6f0ba8c71ef46f3ca8ef383
Author: Michael Stahl <mstahl at redhat.com>
Date: Wed Jun 5 16:50:50 2013 +0200
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
diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index eba4548..a9b73ae 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -30,6 +30,7 @@
#if OSL_DEBUG_LEVEL > 0
#include <iostream>
+#include <set>
#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<sal_Int8> const ns(
+ mxFastTokenHandler->getUTF8Identifier(NAMESPACE(nElement)));
+ Sequence<sal_Int8> const name(
+ mxFastTokenHandler->getUTF8Identifier(TOKEN(nElement)));
+ return OString(reinterpret_cast<sal_Char const*>(ns.getConstArray()), ns.getLength())
+ + OString(reinterpret_cast<sal_Char const*>(maColon.getConstArray()), maColon.getLength())
+ + OString(reinterpret_cast<sal_Char const*>(name.getConstArray()), name.getLength());
+ } else {
+ Sequence<sal_Int8> const name(
+ mxFastTokenHandler->getUTF8Identifier(nElement));
+ return OString(reinterpret_cast<sal_Char const*>(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<OUString> 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 38c8e89..95ebb14 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<sal_Int32> m_DebugStartedElements;
+#endif
+
void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
void write( const OUString& s );
commit 96ee9884b78dce54223e83943a7c5c832ae78759
Author: Michael Stahl <mstahl at redhat.com>
Date: Wed Jun 5 16:48:37 2013 +0200
sax: SaxWriter: 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: I1e32a9fd096463a418a197fcdb3174df79f7a785
diff --git a/sax/source/expatwrap/saxwriter.cxx b/sax/source/expatwrap/saxwriter.cxx
index 20660eb..f49b8c2 100644
--- a/sax/source/expatwrap/saxwriter.cxx
+++ b/sax/source/expatwrap/saxwriter.cxx
@@ -16,8 +16,12 @@
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+
#include <string.h>
+#include <stack>
+#include <set>
+
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/util/XCloneable.hpp>
#include <com/sun/star/xml/sax/XParser.hpp>
@@ -72,6 +76,12 @@ enum SaxInvalidCharacterError
class SaxWriterHelper
{
+#ifdef DBG_UTIL
+public:
+ ::std::stack<OUString> m_DebugStartedElements;
+#endif
+
+private:
Reference< XOutputStream > m_out;
Sequence < sal_Int8 > m_Sequence;
sal_Int8* mp_Sequence;
@@ -80,7 +90,6 @@ class SaxWriterHelper
sal_uInt32 nCurrentPos;
sal_Bool m_bStartElementFinished;
-
inline sal_uInt32 writeSequence() throw( SAXException );
// use only if to insert the bytes more space in the sequence is needed and
@@ -541,6 +550,12 @@ inline void SaxWriterHelper::startDocument() throw( SAXException )
inline SaxInvalidCharacterError SaxWriterHelper::startElement(const OUString& rName, const Reference< XAttributeList >& xAttribs) throw( SAXException )
{
FinishStartElement();
+
+#ifdef DBG_UTIL
+ m_DebugStartedElements.push(rName);
+ ::std::set<OUString> DebugAttributes;
+#endif
+
mp_Sequence[nCurrentPos] = '<';
nCurrentPos++;
if (nCurrentPos == SEQUENCESIZE)
@@ -558,7 +573,13 @@ inline SaxInvalidCharacterError SaxWriterHelper::startElement(const OUString& rN
if (nCurrentPos == SEQUENCESIZE)
nCurrentPos = writeSequence();
- if (!writeString(xAttribs->getNameByIndex( i ), sal_False, sal_False))
+ OUString const& rAttrName(xAttribs->getNameByIndex(i));
+#ifdef DBG_UTIL
+ // Well-formedness constraint: Unique Att Spec
+ assert(DebugAttributes.find(rAttrName) == DebugAttributes.end());
+ DebugAttributes.insert(rAttrName);
+#endif
+ if (!writeString(rAttrName, sal_False, sal_False))
eRet = SAX_ERROR;
mp_Sequence[nCurrentPos] = '=';
@@ -608,6 +629,7 @@ inline sal_Bool SaxWriterHelper::FinishEmptyElement() throw( SAXException )
inline sal_Bool SaxWriterHelper::endElement(const OUString& rName) throw( SAXException )
{
FinishStartElement();
+
mp_Sequence[nCurrentPos] = '<';
nCurrentPos++;
if (nCurrentPos == SEQUENCESIZE)
@@ -1160,6 +1182,14 @@ void SAXWriter::endElement(const OUString& aName) throw (SAXException, Runtime
}
sal_Bool bRet(sal_True);
+ // check here because Helper's endElement is not always called
+#ifdef DBG_UTIL
+ assert(!mp_SaxWriterHelper->m_DebugStartedElements.empty());
+ // Well-formedness constraint: Element Type Match
+ assert(aName == mp_SaxWriterHelper->m_DebugStartedElements.top());
+ mp_SaxWriterHelper->m_DebugStartedElements.pop();
+#endif
+
if( mp_SaxWriterHelper->FinishEmptyElement() )
m_bForceLineBreak = sal_False;
else
commit 350534aba8f82d57782ec22fa4f6b776509beb2d
Author: Michael Stahl <mstahl at redhat.com>
Date: Wed Jun 5 16:44:26 2013 +0200
sc: XLSX export: remove mpAttributes crack:
When there are attributes, XclExpXmlStartElementRecord::SaveXml() would
not call startElement() but instead write the XML element all by itself,
which means there will be an endElement() for which no previous
startElement() was called, which makes checking that these match hard.
Since this silly mpAttributes over-engineering is only used in one place
anyway, give that a separate subclass and use startElement().
There is still an issue with various WriteAttribute methods; if those
are used it's probably not possible to check that for well-formedness.
Change-Id: Id842f000a6fecd77211836705545d58031ebd0f8
diff --git a/sc/source/filter/excel/xepage.cxx b/sc/source/filter/excel/xepage.cxx
index 8e1ffb1..3701887 100644
--- a/sc/source/filter/excel/xepage.cxx
+++ b/sc/source/filter/excel/xepage.cxx
@@ -332,17 +332,26 @@ XclExpPageSettings::XclExpPageSettings( const XclExpRoot& rRoot ) :
maData.maVerPageBreaks.push_back(*itr);
}
-static void lcl_WriteHeaderFooter( XclExpXmlStream& rStrm )
+class XclExpXmlStartHeaderFooterElementRecord : public XclExpXmlElementRecord
+{
+public:
+ explicit XclExpXmlStartHeaderFooterElementRecord(sal_Int32 const nElement)
+ : XclExpXmlElementRecord(nElement) {}
+
+ virtual void SaveXml( XclExpXmlStream& rStrm ) SAL_OVERRIDE;
+};
+
+void XclExpXmlStartHeaderFooterElementRecord::SaveXml(XclExpXmlStream& rStrm)
{
// OOXTODO: we currently only emit oddHeader/oddFooter elements, and
// do not support the first/even/odd page distinction.
- rStrm.WriteAttributes(
+ sax_fastparser::FSHelperPtr& rStream = rStrm.GetCurrentStream();
+ rStream->startElement( mnElement,
// OOXTODO: XML_alignWithMargins,
XML_differentFirst, "false", // OOXTODO
XML_differentOddEven, "false", // OOXTODO
// OOXTODO: XML_scaleWithDoc
FSEND );
- rStrm.GetCurrentStream()->write( ">" );
}
void XclExpPageSettings::Save( XclExpStream& rStrm )
@@ -388,7 +397,7 @@ void XclExpPageSettings::SaveXml( XclExpXmlStream& rStrm )
XclExpSetup( maData ).SaveXml( rStrm );
- XclExpXmlStartElementRecord( XML_headerFooter, lcl_WriteHeaderFooter ).SaveXml( rStrm );
+ XclExpXmlStartHeaderFooterElementRecord(XML_headerFooter).SaveXml(rStrm);
XclExpHeaderFooter( EXC_ID_HEADER, maData.maHeader ).SaveXml( rStrm );
XclExpHeaderFooter( EXC_ID_FOOTER, maData.maFooter ).SaveXml( rStrm );
XclExpXmlEndElementRecord( XML_headerFooter ).SaveXml( rStrm );
diff --git a/sc/source/filter/excel/xerecord.cxx b/sc/source/filter/excel/xerecord.cxx
index b7f2f8e..4c1c5e0 100644
--- a/sc/source/filter/excel/xerecord.cxx
+++ b/sc/source/filter/excel/xerecord.cxx
@@ -57,8 +57,8 @@ void XclExpDelegatingRecord::SaveXml( XclExpXmlStream& rStrm )
// ----------------------------------------------------------------------------
-XclExpXmlElementRecord::XclExpXmlElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) )
- : mnElement( nElement ), mpAttributes( pAttributes )
+XclExpXmlElementRecord::XclExpXmlElementRecord(sal_Int32 const nElement)
+ : mnElement( nElement )
{
}
@@ -68,8 +68,8 @@ XclExpXmlElementRecord::~XclExpXmlElementRecord()
// ----------------------------------------------------------------------------
-XclExpXmlStartElementRecord::XclExpXmlStartElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) )
- : XclExpXmlElementRecord( nElement, pAttributes )
+XclExpXmlStartElementRecord::XclExpXmlStartElementRecord(sal_Int32 const nElement)
+ : XclExpXmlElementRecord(nElement)
{
}
@@ -80,15 +80,9 @@ XclExpXmlStartElementRecord::~XclExpXmlStartElementRecord()
void XclExpXmlStartElementRecord::SaveXml( XclExpXmlStream& rStrm )
{
sax_fastparser::FSHelperPtr& rStream = rStrm.GetCurrentStream();
- if( ! mpAttributes )
- {
- rStream->startElement( mnElement, FSEND );
- }
- else
- {
- rStream->write( "<" )->writeId( mnElement );
- (*mpAttributes)( rStrm );
- }
+ // TODO: no generic way to add attributes here, but it appears to
+ // not be needed yet
+ rStream->startElement( mnElement, FSEND );
}
// ----------------------------------------------------------------------------
@@ -109,8 +103,9 @@ void XclExpXmlEndElementRecord::SaveXml( XclExpXmlStream& rStrm )
// ----------------------------------------------------------------------------
-XclExpXmlStartSingleElementRecord::XclExpXmlStartSingleElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) )
- : XclExpXmlElementRecord( nElement, pAttributes )
+XclExpXmlStartSingleElementRecord::XclExpXmlStartSingleElementRecord(
+ sal_Int32 const nElement)
+ : XclExpXmlElementRecord( nElement )
{
}
@@ -122,8 +117,6 @@ void XclExpXmlStartSingleElementRecord::SaveXml( XclExpXmlStream& rStrm )
{
sax_fastparser::FSHelperPtr& rStream = rStrm.GetCurrentStream();
rStream->write( "<" )->writeId( mnElement );
- if( mpAttributes )
- (*mpAttributes)( rStrm );
}
// ----------------------------------------------------------------------------
diff --git a/sc/source/filter/inc/xerecord.hxx b/sc/source/filter/inc/xerecord.hxx
index 27f272e..78241e8 100644
--- a/sc/source/filter/inc/xerecord.hxx
+++ b/sc/source/filter/inc/xerecord.hxx
@@ -61,12 +61,11 @@ private:
class XclExpXmlElementRecord : public XclExpRecordBase
{
public:
- XclExpXmlElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
+ explicit XclExpXmlElementRecord(sal_Int32 nElement);
virtual ~XclExpXmlElementRecord();
protected:
sal_Int32 mnElement;
- void (*mpAttributes)( XclExpXmlStream& rStrm );
};
// ----------------------------------------------------------------------------
@@ -74,11 +73,11 @@ protected:
class XclExpXmlStartElementRecord : public XclExpXmlElementRecord
{
public:
- XclExpXmlStartElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
+ explicit XclExpXmlStartElementRecord(sal_Int32 nElement);
virtual ~XclExpXmlStartElementRecord();
/** Starts the element nElement */
- virtual void SaveXml( XclExpXmlStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm ) SAL_OVERRIDE;
};
// ----------------------------------------------------------------------------
@@ -86,11 +85,11 @@ public:
class XclExpXmlEndElementRecord : public XclExpXmlElementRecord
{
public:
- XclExpXmlEndElementRecord( sal_Int32 nElement );
+ explicit XclExpXmlEndElementRecord(sal_Int32 nElement);
virtual ~XclExpXmlEndElementRecord();
/** Ends the element nElement */
- virtual void SaveXml( XclExpXmlStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm ) SAL_OVERRIDE;
};
// ----------------------------------------------------------------------------
@@ -98,11 +97,11 @@ public:
class XclExpXmlStartSingleElementRecord : public XclExpXmlElementRecord
{
public:
- XclExpXmlStartSingleElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
+ explicit XclExpXmlStartSingleElementRecord(sal_Int32 nElement);
virtual ~XclExpXmlStartSingleElementRecord();
/** Starts the single element nElement */
- virtual void SaveXml( XclExpXmlStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm ) SAL_OVERRIDE;
};
// ----------------------------------------------------------------------------
@@ -114,7 +113,7 @@ public:
virtual ~XclExpXmlEndSingleElementRecord();
/** Ends the single element nElement */
- virtual void SaveXml( XclExpXmlStream& rStrm );
+ virtual void SaveXml( XclExpXmlStream& rStrm ) SAL_OVERRIDE;
};
// ----------------------------------------------------------------------------
diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx
index 0ac31d4..4b37a68 100644
--- a/sc/source/filter/inc/xestream.hxx
+++ b/sc/source/filter/inc/xestream.hxx
@@ -313,6 +313,7 @@ public:
sax_fastparser::FSHelperPtr GetStreamForPath( const OUString& rPath );
+ // FIXME: if written through this cannot be checked for well-formedness
sax_fastparser::FSHelperPtr& WriteAttributes( sal_Int32 nAttribute, const char* value, FSEND_t )
{ return WriteAttributesInternal( nAttribute, value, FSEND_internal ); }
sax_fastparser::FSHelperPtr& WriteAttributes( sal_Int32 nAttribute, const OString& value, FSEND_t )
More information about the Libreoffice-commits
mailing list