From 144fb9a6d644b69169e3be917205864210667bee Mon Sep 17 00:00:00 2001 From: Jez Higgins Date: Sat, 9 Oct 2010 23:10:35 +0100 Subject: [PATCH] Disallow variable references in xsl:key match and use expressions --- include/XPath/impl/xpath_parser.hpp | 2 +- .../XSLT/impl/handler/xslt_key_handler.hpp | 13 +++++-- .../XSLT/impl/xslt_compilation_context.hpp | 38 ++++++++++++++++--- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/include/XPath/impl/xpath_parser.hpp b/include/XPath/impl/xpath_parser.hpp index dea1669a..45e33198 100644 --- a/include/XPath/impl/xpath_parser.hpp +++ b/include/XPath/impl/xpath_parser.hpp @@ -121,7 +121,7 @@ public: const VariableResolver& getVariableResolver() const { return variableResolver_.get(); } void resetVariableResolver() { variableResolver_.set(VariableResolverPtr(new NullVariableResolver())); } - void setVariableCompileTimeResolver(const VariableResolver& ctVariableResolver) { ctVariableResolver_.set(ctVariableResolver); } + void setVariableCompileTimeResolver(const VariableCompileTimeResolver& ctVariableResolver) { ctVariableResolver_.set(ctVariableResolver); } void setVariableCompileTimeResolver(VariableCompileTimeResolverPtr ctVariableResolver) { ctVariableResolver_.set(ctVariableResolver); } const VariableCompileTimeResolver& getVariableCompileTimeResolver() const { return ctVariableResolver_.get(); } void resetVariableCompileTimeResolver() { ctVariableResolver_.set(VariableCompileTimeResolverPtr(new DefaultVariableCompileTimeResolver())); } diff --git a/include/XSLT/impl/handler/xslt_key_handler.hpp b/include/XSLT/impl/handler/xslt_key_handler.hpp index 71000afd..5b2fd949 100644 --- a/include/XSLT/impl/handler/xslt_key_handler.hpp +++ b/include/XSLT/impl/handler/xslt_key_handler.hpp @@ -33,10 +33,17 @@ public: std::map attrs = gatherAttributes(qName, atts, rules); name_ = context_.processInternalQName(attrs["name"]).clarkName(); - Key::MatchExprList matches = context_.xpath_match(attrs["match"]); - Arabica::XPath::XPathExpression use = context_.xpath_expression(attrs["use"]); + try + { + Key::MatchExprList matches = context_.xpath_match_no_variables(attrs["match"]); + Arabica::XPath::XPathExpression use = context_.xpath_expression_no_variables(attrs["use"]); - key_ = new Key(matches, use); + key_ = new Key(matches, use); + } // try + catch(const Arabica::XPath::UnboundVariableException& uve) + { + throw SAX::SAXException("Variable references are not allowed in xsl:key match and use expressions"); + } // catch } // startElement virtual void endElement(const std::string& /* namespaceURI */, diff --git a/include/XSLT/impl/xslt_compilation_context.hpp b/include/XSLT/impl/xslt_compilation_context.hpp index 4fc5fa1e..2d4c54ad 100644 --- a/include/XSLT/impl/xslt_compilation_context.hpp +++ b/include/XSLT/impl/xslt_compilation_context.hpp @@ -18,9 +18,13 @@ class CompiledStylesheet; class ItemContainer; class CompilationContext : - private Arabica::XPath::FunctionResolver, - private Arabica::XPath::NamespaceContext > + private Arabica::XPath::FunctionResolver >, + private Arabica::XPath::NamespaceContext >, + private Arabica::XPath::DefaultVariableCompileTimeResolver > { +private: + typedef Arabica::XPath::DefaultVariableCompileTimeResolver > CTVariableResolverT; + public: CompilationContext(StylesheetParser& parser, CompiledStylesheet& stylesheet) : @@ -28,10 +32,12 @@ public: stylesheet_(stylesheet), autoNs_(1), current_allowed_(false), + variables_allowed_(true), precedence_(Precedence::InitialPrecedence()) { xpath_.setNamespaceContext(*this); xpath_.setFunctionResolver(*this); + xpath_.setVariableCompileTimeResolver(*this); } // CompilationContext ~CompilationContext() @@ -51,11 +57,22 @@ public: StylesheetParser& parser() const { return parser_; } Arabica::XPath::XPathExpressionPtr xpath_expression(const std::string& expr) const { return xpath_.compile_expr(expr); } + Arabica::XPath::XPathExpressionPtr xpath_expression_no_variables(const std::string& expr) const + { + Disallow variables(variables_allowed_); + return xpath_expression(expr); + } // xpath_expression_no_variables std::vector > xpath_match(const std::string& match) const { - DisallowCurrent guard(current_allowed_); + Disallow current(current_allowed_); return xpath_.compile_match(match); } // xpath_match + std::vector > xpath_match_no_variables(const std::string& match) const + { + Disallow variables(variables_allowed_); + return xpath_match(match); + } // xpath_match_no_variables + Arabica::XPath::XPathExpressionPtr xpath_attribute_value_template(const std::string& expr) const { return xpath_.compile_attribute_value_template(expr); } CompiledStylesheet& stylesheet() const { return stylesheet_; } @@ -161,6 +178,14 @@ public: } // precedence private: + virtual Arabica::XPath::XPathExpression_impl >* + compileVariable(const std::string& namespace_uri, const std::string& name) const + { + if(!variables_allowed_) + return 0; + return CTVariableResolverT::compileVariable(namespace_uri, name); + } // compileVariable + // FunctionResolver virtual Arabica::XPath::XPathFunction* resolveFunction( const std::string& namespace_uri, @@ -227,6 +252,7 @@ private: CompiledStylesheet& stylesheet_; mutable int autoNs_; mutable bool current_allowed_; + mutable bool variables_allowed_; Precedence precedence_; Arabica::XPath::XPath xpath_; std::stack*> handlerStack_; @@ -235,11 +261,11 @@ private: CompilationContext(const CompilationContext&); - class DisallowCurrent + class Disallow { public: - DisallowCurrent(bool& allow) : allow_(allow) { allow_ = false; } - ~DisallowCurrent() { allow_ = true; } + Disallow(bool& allow) : allow_(allow) { allow_ = false; } + ~Disallow() { allow_ = true; } private: bool& allow_; }; // DisallowCurrent