diff options
author | Adrian Kummerländer | 2014-05-29 23:01:36 +0200 |
---|---|---|
committer | Adrian Kummerländer | 2014-05-29 23:01:36 +0200 |
commit | e402a092a5e2fbf624947896b013d405efb75049 (patch) | |
tree | fc43b178b39ff56669de5e9d3778019347e88d9a | |
parent | 3bc793d95293d40dbab62c593ce4ceaa86fae25b (diff) | |
download | InputXSLT-e402a092a5e2fbf624947896b013d405efb75049.tar InputXSLT-e402a092a5e2fbf624947896b013d405efb75049.tar.gz InputXSLT-e402a092a5e2fbf624947896b013d405efb75049.tar.bz2 InputXSLT-e402a092a5e2fbf624947896b013d405efb75049.tar.lz InputXSLT-e402a092a5e2fbf624947896b013d405efb75049.tar.xz InputXSLT-e402a092a5e2fbf624947896b013d405efb75049.tar.zst InputXSLT-e402a092a5e2fbf624947896b013d405efb75049.zip |
Fixed error handling of invalid XSL transformations
* xalan is segfaulting in XalanDOMString constructor when the static member "XalanLocator::getSystemId" is returning null-pointer
** this should seemingly be handled by passing a pointer to the static constant m_dummy but this sadly fails to prevent the segfault
** the patch provided by this commit fixes the problem for now but I cannot guarantee that this wont cause any side effects in a other context
* Adapted TransformationFacade to handle errors during transformation compilation
** errors generated during transformation compilation are returned through the generate member method
** throwing an exeception during TransformationFacade construction would require additional error handling in the calling code
* Added xalan::ProblemListener functionality to the ErrorHandler class
** XSLT problems passed to the ProblemListener are returned alongside to and treated as all other transformation errors
-rw-r--r-- | patch/XSLException.patch | 15 | ||||
-rw-r--r-- | src/support/error_handler.cc | 47 | ||||
-rw-r--r-- | src/support/error_handler.h | 34 | ||||
-rw-r--r-- | src/transformation_facade.cc | 28 |
4 files changed, 105 insertions, 19 deletions
diff --git a/patch/XSLException.patch b/patch/XSLException.patch new file mode 100644 index 0000000..a67f265 --- /dev/null +++ b/patch/XSLException.patch @@ -0,0 +1,15 @@ +--- xalan-c-1.11_original/c/src/xalanc/PlatformSupport/XSLException.cpp 2014-05-29 22:27:20.366792350 +0200 ++++ xalan-c-1.11_patched/c/src/xalanc/PlatformSupport/XSLException.cpp 2014-05-29 22:56:01.136185453 +0200 +@@ -41,11 +41,7 @@ + const Locator* theLocator) : + m_memoryManager(theManager), + m_message(theMessage, theManager), +- m_uri( +- XalanLocator::getSystemId( +- theLocator, +- &s_dummy), +- theManager), ++ m_uri(theLocator == 0 ? s_dummy : theLocator->getSystemId()), + m_lineNumber(XalanLocator::getLineNumber(theLocator)), + m_columnNumber(XalanLocator::getColumnNumber(theLocator)), + m_formatted(false) diff --git a/src/support/error_handler.cc b/src/support/error_handler.cc index db54225..2ca721d 100644 --- a/src/support/error_handler.cc +++ b/src/support/error_handler.cc @@ -4,6 +4,7 @@ #include <iostream> +#include "support/xalan_string.h" #include "support/xerces_string_guard.h" namespace { @@ -47,6 +48,52 @@ void ErrorHandler::fatalError(const xercesc::SAXParseException& exception) { void ErrorHandler::resetErrors() { } +void ErrorHandler::problem( + xalan::ProblemListenerBase::eSource, + xalan::ProblemListenerBase::eClassification, + const xalan::XalanDOMString& message, + const xalan::Locator*, + const xalan::XalanNode* +) { + this->constructErrorCache(); + + this->error_cache_->emplace_back( + "XSLT problem: " + toString(message) + ); +} + +void ErrorHandler::problem( + xalan::ProblemListenerBase::eSource, + xalan::ProblemListenerBase::eClassification, + const xalan::XalanNode*, + const xalan::ElemTemplateElement*, + const xalan::XalanDOMString& message, + const xalan::XalanDOMChar*, + xalan::XalanFileLoc, + xalan::XalanFileLoc +) { + this->constructErrorCache(); + + this->error_cache_->emplace_back( + "XSLT problem: " + toString(message) + ); +} + +void ErrorHandler::problem( + xalan::ProblemListenerBase::eSource, + xalan::ProblemListenerBase::eClassification, + const xalan::XalanDOMString& message, + const xalan::XalanNode* +) { + this->constructErrorCache(); + + this->error_cache_->emplace_back( + "XSLT problem: " + toString(message) + ); +} + +void ErrorHandler::setPrintWriter(xalan::PrintWriter*) { } + auto ErrorHandler::getCachedErrors() -> error_cache_ptr { return error_cache_ptr(this->error_cache_.release()); } diff --git a/src/support/error_handler.h b/src/support/error_handler.h index 77a46d8..02d741e 100644 --- a/src/support/error_handler.h +++ b/src/support/error_handler.h @@ -2,14 +2,18 @@ #define INPUTXSLT_SRC_SUPPORT_ERROR_HANDLER_H_ #include <xercesc/sax/ErrorHandler.hpp> +#include <xalanc/XSLT/ProblemListener.hpp> #include <memory> #include <vector> #include <string> +#include "common.h" + namespace InputXSLT { -class ErrorHandler : public xercesc::ErrorHandler { +class ErrorHandler : public xercesc::ErrorHandler, + public xalan::ProblemListener { public: typedef std::vector<std::string> error_cache; typedef std::unique_ptr<error_cache> error_cache_ptr; @@ -21,6 +25,34 @@ class ErrorHandler : public xercesc::ErrorHandler { virtual void fatalError(const xercesc::SAXParseException&); virtual void resetErrors(); + virtual void problem( + xalan::ProblemListenerBase::eSource, + xalan::ProblemListenerBase::eClassification, + const xalan::XalanDOMString&, + const xalan::Locator*, + const xalan::XalanNode* + ); + + virtual void problem( + xalan::ProblemListenerBase::eSource, + xalan::ProblemListenerBase::eClassification, + const xalan::XalanNode*, + const xalan::ElemTemplateElement*, + const xalan::XalanDOMString&, + const xalan::XalanDOMChar*, + xalan::XalanFileLoc, + xalan::XalanFileLoc + ); + + virtual void problem( + xalan::ProblemListenerBase::eSource, + xalan::ProblemListenerBase::eClassification, + const xalan::XalanDOMString&, + const xalan::XalanNode* + ); + + virtual void setPrintWriter(xalan::PrintWriter*); + error_cache_ptr getCachedErrors(); private: diff --git a/src/transformation_facade.cc b/src/transformation_facade.cc index 0f174d8..8b9e1a2 100644 --- a/src/transformation_facade.cc +++ b/src/transformation_facade.cc @@ -18,6 +18,7 @@ TransformationFacade::TransformationFacade( error_handler_() { this->transformer_.setEntityResolver(resolver); this->transformer_.setErrorHandler(&this->error_handler_); + this->transformer_.setProblemListener(&this->error_handler_); this->transformer_.compileStylesheet( xalan::XSLTInputSource(transformation.data()), @@ -66,27 +67,18 @@ auto TransformationFacade::generate( xalan::XSLTResultTarget&& outputTarget, StylesheetParameterGuard& ) -> return_type { - std::stringstream emptyStream("<dummy/>"); - xalan::XSLTInputSource inputSource(emptyStream); - - const int resultCode = this->transformer_.transform( - inputSource, - this->transformation_, - outputTarget - ); - - return_type errors(this->error_handler_.getCachedErrors()); - - if ( errors && resultCode != 0 ) { - errors->emplace_back( - "Transformation error with code " + - std::to_string(resultCode) + - ": " + - this->transformer_.getLastError() + if ( this->transformation_ != nullptr ) { + std::stringstream emptyStream("<dummy/>"); + xalan::XSLTInputSource inputSource(emptyStream); + + this->transformer_.transform( + inputSource, + this->transformation_, + outputTarget ); } - return errors; + return this->error_handler_.getCachedErrors(); } } |