aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerländer2014-05-29 23:01:36 +0200
committerAdrian Kummerländer2014-05-29 23:01:36 +0200
commite402a092a5e2fbf624947896b013d405efb75049 (patch)
treefc43b178b39ff56669de5e9d3778019347e88d9a
parent3bc793d95293d40dbab62c593ce4ceaa86fae25b (diff)
downloadInputXSLT-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.patch15
-rw-r--r--src/support/error_handler.cc47
-rw-r--r--src/support/error_handler.h34
-rw-r--r--src/transformation_facade.cc28
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();
}
}