summaryrefslogtreecommitdiff
path: root/unoxml
diff options
context:
space:
mode:
authorFyodor Yemelyanenko <fyodor_e@hotmail.com>2017-08-21 16:11:14 +1000
committerMichael Stahl <mstahl@redhat.com>2017-08-25 12:44:33 +0200
commitd181d8acbf49e2fe87c8cf53a9431e503ccced55 (patch)
tree5a9049f86deed322dadb912f00113fc26f2a77e7 /unoxml
parent3aab0593dd0b64849488f2186221135df9851258 (diff)
tdf#84237 use XErrorHandler in CDocumentBuilder
In documentbuilder.cxx added code to call XErrorHandler::warning and XErrorHandler::error functions (from DOM::warning_func and DOM::error_func) In domtest.cxx added try {} catch () block to BasicTest::validInputTest, BasicTest::warningInputTest and BasicTest::errorInputTest and to SerializerTest::serializerTest. Also uncommented lines CPPUNIT_TEST(warningInputTest); and CPPUNIT_TEST(errorInputTest); Unit tests are now working (FatalError test removed, as lib2xml doesn't distinguish between error and fatal error and counts everything as error). Change-Id: I27c5036df6a1cc5bef5dbb8171c201d81bae2ccd Reviewed-on: https://gerrit.libreoffice.org/41376 Reviewed-by: Michael Stahl <mstahl@redhat.com> Tested-by: Michael Stahl <mstahl@redhat.com>
Diffstat (limited to 'unoxml')
-rw-r--r--unoxml/qa/unit/domtest.cxx161
-rw-r--r--unoxml/source/dom/documentbuilder.cxx68
-rw-r--r--unoxml/source/dom/documentbuilder.hxx11
3 files changed, 162 insertions, 78 deletions
diff --git a/unoxml/qa/unit/domtest.cxx b/unoxml/qa/unit/domtest.cxx
index 6080020e7647..18e37a8fa297 100644
--- a/unoxml/qa/unit/domtest.cxx
+++ b/unoxml/qa/unit/domtest.cxx
@@ -37,6 +37,7 @@
#include <com/sun/star/xml/sax/FastToken.hpp>
#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
using namespace ::comphelper;
using namespace ::com::sun::star;
@@ -61,16 +62,20 @@ static const char validTestFile[] =
</office:document-content> \
";
-// generates a warning: unsupported xml version, unknown xml:space
+// generates a warning: unknown xml:space
// value
static const char warningTestFile[] =
-"<?xml version=\"47-11.0\" encoding=\"UTF-8\"?> \
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?> \
<office:document-content \
xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \
- xml:space=\"blafasl\" \
+ xml:space=\"blah\" \
+ xmlns:xlink=\"http://www.w3.org/1999/xlink\" \
office:version=\"1.0\"> \
<office:scripts/> \
- <office:automatic-styles/> \
+ <xlink:test/> \
+ <office:automatic-styles teststyle=\"test\"/> \
+ <moretest/> \
+ some text \303\266\303\244\303\274 \
</office:document-content> \
";
@@ -85,19 +90,17 @@ static const char errorTestFile[] =
</office:document-content> \
";
-// plain empty
-static const char fatalTestFile[] = "";
-
struct ErrorHandler
: public ::cppu::WeakImplHelper< xml::sax::XErrorHandler >
{
sal_uInt32 mnErrCount;
- sal_uInt32 mnFatalCount;
+// sal_uInt32 mnFatalCount; // No fatal error counter, as lib2xml doesn't distinguish between error and fatal error
+ // (see See xmlFatalErrMsg from lib2xml/parse.c and __xmlRaiseError from lib2xml/error.c)
sal_uInt32 mnWarnCount;
- bool noErrors() const { return !mnErrCount && !mnFatalCount && !mnWarnCount; }
+ bool noErrors() const { return !mnErrCount /*&& !mnFatalCount*/ && !mnWarnCount; }
- ErrorHandler() : mnErrCount(0), mnFatalCount(0), mnWarnCount(0)
+ ErrorHandler() : mnErrCount(0), /*mnFatalCount(0),*/ mnWarnCount(0)
{}
virtual void SAL_CALL error( const uno::Any& ) override
@@ -105,9 +108,11 @@ struct ErrorHandler
++mnErrCount;
}
+ // Just implement FatalError function as it is in XErrorHandler
+ // This function is never used, as lib2xml doesn't distinguish between error and fatalerror and calls error functions in both cases
virtual void SAL_CALL fatalError( const uno::Any& ) override
{
- ++mnFatalCount;
+ //++mnFatalCount;
}
virtual void SAL_CALL warning( const uno::Any& ) override
@@ -195,7 +200,6 @@ struct BasicTest : public test::BootstrapFixture
rtl::Reference<SequenceInputStream> mxValidInStream;
rtl::Reference<SequenceInputStream> mxWarningInStream;
rtl::Reference<SequenceInputStream> mxErrorInStream;
- rtl::Reference<SequenceInputStream> mxFatalInStream;
virtual void setUp() override
{
@@ -207,58 +211,70 @@ struct BasicTest : public test::BootstrapFixture
mxValidInStream.set( new SequenceInputStream(css::uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8 const *>(validTestFile), SAL_N_ELEMENTS(validTestFile))) );
mxWarningInStream.set( new SequenceInputStream(css::uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8 const *>(warningTestFile), SAL_N_ELEMENTS(warningTestFile))) );
mxErrorInStream.set( new SequenceInputStream(css::uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8 const *>(errorTestFile), SAL_N_ELEMENTS(errorTestFile))) );
- mxFatalInStream.set( new SequenceInputStream(css::uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8 const *>(fatalTestFile), SAL_N_ELEMENTS(fatalTestFile))) );
mxDomBuilder->setErrorHandler(mxErrHandler.get());
}
void validInputTest()
{
- CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #1",
- mxDomBuilder->parse(
- uno::Reference<io::XInputStream>(
- mxValidInStream.get())).is() );
- CPPUNIT_ASSERT_MESSAGE( "Valid input file resulted in parse errors",
- mxErrHandler->noErrors() );
+ try
+ {
+ CPPUNIT_ASSERT_MESSAGE("Valid input file did not result in XDocument #1",
+ mxDomBuilder->parse(
+ uno::Reference<io::XInputStream>(
+ mxValidInStream.get())).is());
+ CPPUNIT_ASSERT_MESSAGE("Valid input file resulted in parse errors",
+ mxErrHandler->noErrors());
+ }
+ catch (const css::xml::sax::SAXParseException&)
+ {
+ CPPUNIT_ASSERT_MESSAGE("Valid input file did not result in XDocument (exception thrown)", false);
+ }
}
-/*
+
void warningInputTest()
{
- CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #2",
- mxDomBuilder->parse(
- uno::Reference<io::XInputStream>(
- mxWarningInStream.get())).is() );
- CPPUNIT_ASSERT_MESSAGE( "No parse warnings in unclean input file",
- mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount );
+ try
+ {
+ // We DONT expect exeption here, as mxWarningInStream is valid XML Doc
+ CPPUNIT_ASSERT_MESSAGE("Valid input file did not result in XDocument #2",
+ mxDomBuilder->parse(
+ uno::Reference<io::XInputStream>(
+ mxWarningInStream.get())).is());
+ }
+ catch (const css::xml::sax::SAXParseException& )
+ {
+ CPPUNIT_ASSERT_MESSAGE("Valid input file did not result in XDocument #2 (exception thrown)", false);
+ }
+ CPPUNIT_ASSERT_MESSAGE("No parse warnings in unclean input file",
+ mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount /*&& !mxErrHandler->mnFatalCount*/);
}
void errorInputTest()
{
- CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #3",
- mxDomBuilder->parse(
- uno::Reference<io::XInputStream>(
- mxErrorInStream.get())).is() );
- CPPUNIT_ASSERT_MESSAGE( "No parse errors in unclean input file",
- !mxErrHandler->mnWarnCount && mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount );
+ try
+ {
+ // We expect exeption here, as mxErrorInStream is invalid XML Doc
+ CPPUNIT_ASSERT_MESSAGE("Invalid input file result in XDocument #2!",
+ !mxDomBuilder->parse(
+ uno::Reference<io::XInputStream>(
+ mxErrorInStream.get())).is());
+ CPPUNIT_ASSERT_MESSAGE("No exception is thrown in unclean input file", false);
+ }
+ catch (const css::xml::sax::SAXParseException&)
+ {
+ // It's OK to catch an exeption here as we parse incorrect XML file
+ }
+ CPPUNIT_ASSERT_MESSAGE("No parse errors in unclean input file",
+ !mxErrHandler->mnWarnCount && mxErrHandler->mnErrCount /*&& !mxErrHandler->mnFatalCount*/);
}
- void fatalInputTest()
- {
- CPPUNIT_ASSERT_MESSAGE( "Broken input file resulted in XDocument",
- !mxDomBuilder->parse(
- uno::Reference<io::XInputStream>(
- mxFatalInStream.get())).is() );
- CPPUNIT_ASSERT_MESSAGE( "No fatal parse errors in unclean input file",
- !mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && mxErrHandler->mnFatalCount );
- };
-*/
- // Change the following lines only, if you add, remove or rename
+ // Change the following lines only, if you add, remove or rename
// member functions of the current class,
// because these macros are need by auto register mechanism.
CPPUNIT_TEST_SUITE(BasicTest);
CPPUNIT_TEST(validInputTest);
- //CPPUNIT_TEST(warningInputTest);
- //CPPUNIT_TEST(errorInputTest);
- //CPPUNIT_TEST(fatalInputTest);
+ CPPUNIT_TEST(warningInputTest);
+ CPPUNIT_TEST(errorInputTest);
CPPUNIT_TEST_SUITE_END();
};
@@ -294,29 +310,36 @@ struct SerializerTest : public test::BootstrapFixture
void serializerTest ()
{
- uno::Reference< xml::dom::XDocument > xDoc=
- mxDomBuilder->parse(
- uno::Reference<io::XInputStream>(
- mxInStream.get()));
- CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument",
- xDoc.is() );
- CPPUNIT_ASSERT_MESSAGE( "Valid input file resulted in parse errors",
- mxErrHandler->noErrors() );
-
- uno::Reference< xml::sax::XSAXSerializable > xSaxSerializer(
- xDoc, uno::UNO_QUERY);
- CPPUNIT_ASSERT_MESSAGE( "XSAXSerializable not supported",
- xSaxSerializer.is() );
-
- uno::Reference< xml::sax::XFastSAXSerializable > xFastSaxSerializer(
- xDoc, uno::UNO_QUERY);
- CPPUNIT_ASSERT_MESSAGE( "XFastSAXSerializable not supported",
- xSaxSerializer.is() );
-
- xFastSaxSerializer->fastSerialize( mxHandler.get(),
- mxTokHandler.get(),
- uno::Sequence< beans::StringPair >(),
- maRegisteredNamespaces );
+ try
+ {
+ uno::Reference< xml::dom::XDocument > xDoc =
+ mxDomBuilder->parse(
+ uno::Reference<io::XInputStream>(
+ mxInStream.get()));
+ CPPUNIT_ASSERT_MESSAGE("Valid input file did not result in XDocument",
+ xDoc.is());
+ CPPUNIT_ASSERT_MESSAGE("Valid input file resulted in parse errors",
+ mxErrHandler->noErrors());
+
+ uno::Reference< xml::sax::XSAXSerializable > xSaxSerializer(
+ xDoc, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_MESSAGE("XSAXSerializable not supported",
+ xSaxSerializer.is());
+
+ uno::Reference< xml::sax::XFastSAXSerializable > xFastSaxSerializer(
+ xDoc, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_MESSAGE("XFastSAXSerializable not supported",
+ xSaxSerializer.is());
+
+ xFastSaxSerializer->fastSerialize(mxHandler.get(),
+ mxTokHandler.get(),
+ uno::Sequence< beans::StringPair >(),
+ maRegisteredNamespaces);
+ }
+ catch (const css::xml::sax::SAXParseException&)
+ {
+ CPPUNIT_ASSERT_MESSAGE("Valid input file did not result in XDocument (exception thrown)", false);
+ }
}
// Change the following lines only, if you add, remove or rename
diff --git a/unoxml/source/dom/documentbuilder.cxx b/unoxml/source/dom/documentbuilder.cxx
index 5f3530395bfe..e8eb6097c23d 100644
--- a/unoxml/source/dom/documentbuilder.cxx
+++ b/unoxml/source/dom/documentbuilder.cxx
@@ -269,21 +269,71 @@ namespace DOM
// default warning handler does not trigger assertion
static void warning_func(void * ctx, const char * /*msg*/, ...)
{
- SAL_INFO(
- "unoxml",
- "libxml2 warning: "
- << make_error_message(static_cast<xmlParserCtxtPtr>(ctx)));
+ try
+ {
+ xmlParserCtxtPtr const pctx = static_cast<xmlParserCtxtPtr>(ctx);
+
+ SAL_INFO(
+ "unoxml",
+ "libxml2 warning: "
+ << make_error_message(pctx));
+
+ CDocumentBuilder * const pDocBuilder = static_cast<CDocumentBuilder*>(pctx->_private);
+
+ if (pDocBuilder->getErrorHandler().is()) // if custom error handler is set (using setErrorHandler ())
+ {
+ // Prepare SAXParseException to be passed to custom XErrorHandler::warning function
+ css::xml::sax::SAXParseException saxex;
+ saxex.Message = make_error_message(pctx);
+ saxex.LineNumber = static_cast<sal_Int32>(pctx->lastError.line);
+ saxex.ColumnNumber = static_cast<sal_Int32>(pctx->lastError.int2);
+
+ // Call custom warning function
+ pDocBuilder->getErrorHandler()->warning(::css::uno::Any(saxex));
+ }
+ }
+ catch (const css::uno::RuntimeException &e)
+ {
+ // Protect lib2xml from UNO Exception
+ SAL_WARN("unoxml",
+ "DOM::warning_func: caught RuntimeException"
+ << e.Message);
+ }
}
// default error handler triggers assertion
static void error_func(void * ctx, const char * /*msg*/, ...)
{
- SAL_WARN(
- "unoxml",
- "libxml2 error: "
- << make_error_message(static_cast<xmlParserCtxtPtr>(ctx)));
+ try
+ {
+ xmlParserCtxtPtr const pctx = static_cast<xmlParserCtxtPtr>(ctx);
+ SAL_WARN(
+ "unoxml",
+ "libxml2 error: "
+ << make_error_message(pctx));
+
+ CDocumentBuilder * const pDocBuilder = static_cast<CDocumentBuilder*>(pctx->_private);
+
+ if (pDocBuilder->getErrorHandler().is()) // if custom error handler is set (using setErrorHandler ())
+ {
+ // Prepare SAXParseException to be passed to custom XErrorHandler::error function
+ css::xml::sax::SAXParseException saxex;
+ saxex.Message = make_error_message(pctx);
+ saxex.LineNumber = static_cast<sal_Int32>(pctx->lastError.line);
+ saxex.ColumnNumber = static_cast<sal_Int32>(pctx->lastError.int2);
+
+ // Call custom warning function
+ pDocBuilder->getErrorHandler()->error(::css::uno::Any(saxex));
+ }
+ }
+ catch (const css::uno::RuntimeException &e)
+ {
+ // Protect lib2xml from UNO Exception
+ SAL_WARN("unoxml",
+ "DOM::error_func: caught RuntimeException"
+ << e.Message);
+ }
}
-
} // extern "C"
void throwEx(xmlParserCtxtPtr ctxt)
diff --git a/unoxml/source/dom/documentbuilder.hxx b/unoxml/source/dom/documentbuilder.hxx
index cdda893010d5..9f6253bdff8a 100644
--- a/unoxml/source/dom/documentbuilder.hxx
+++ b/unoxml/source/dom/documentbuilder.hxx
@@ -123,6 +123,17 @@ namespace DOM
the XML document to be parsed.
*/
virtual void SAL_CALL setErrorHandler(const css::uno::Reference< css::xml::sax::XErrorHandler >& eh) override;
+
+ /*
+ Get the ErrorHandler to be used to report errors present in
+ the XML document to be parsed.
+ */
+
+ const css::uno::Reference< css::xml::sax::XErrorHandler >& getErrorHandler()
+ {
+ return m_xErrorHandler;
+ }
+
};
}