Disallow variable references in xsl:key match and use expressions

This commit is contained in:
Jez Higgins 2010-10-09 23:10:35 +01:00
parent ffec8d53b9
commit 144fb9a6d6
3 changed files with 43 additions and 10 deletions

View file

@ -121,7 +121,7 @@ public:
const VariableResolver<string_type, string_adaptor>& getVariableResolver() const { return variableResolver_.get(); }
void resetVariableResolver() { variableResolver_.set(VariableResolverPtr<string_type, string_adaptor>(new NullVariableResolver<string_type, string_adaptor>())); }
void setVariableCompileTimeResolver(const VariableResolver<string_type, string_adaptor>& ctVariableResolver) { ctVariableResolver_.set(ctVariableResolver); }
void setVariableCompileTimeResolver(const VariableCompileTimeResolver<string_type, string_adaptor>& ctVariableResolver) { ctVariableResolver_.set(ctVariableResolver); }
void setVariableCompileTimeResolver(VariableCompileTimeResolverPtr<string_type, string_adaptor> ctVariableResolver) { ctVariableResolver_.set(ctVariableResolver); }
const VariableCompileTimeResolver<string_type, string_adaptor>& getVariableCompileTimeResolver() const { return ctVariableResolver_.get(); }
void resetVariableCompileTimeResolver() { ctVariableResolver_.set(VariableCompileTimeResolverPtr<string_type, string_adaptor>(new DefaultVariableCompileTimeResolver<string_type, string_adaptor>())); }

View file

@ -33,10 +33,17 @@ public:
std::map<std::string, std::string> attrs = gatherAttributes(qName, atts, rules);
name_ = context_.processInternalQName(attrs["name"]).clarkName();
Key::MatchExprList matches = context_.xpath_match(attrs["match"]);
Arabica::XPath::XPathExpression<std::string> use = context_.xpath_expression(attrs["use"]);
try
{
Key::MatchExprList matches = context_.xpath_match_no_variables(attrs["match"]);
Arabica::XPath::XPathExpression<std::string> 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 */,

View file

@ -18,9 +18,13 @@ class CompiledStylesheet;
class ItemContainer;
class CompilationContext :
private Arabica::XPath::FunctionResolver<std::string>,
private Arabica::XPath::NamespaceContext<std::string, Arabica::default_string_adaptor<std::string> >
private Arabica::XPath::FunctionResolver<std::string, Arabica::default_string_adaptor<std::string> >,
private Arabica::XPath::NamespaceContext<std::string, Arabica::default_string_adaptor<std::string> >,
private Arabica::XPath::DefaultVariableCompileTimeResolver<std::string, Arabica::default_string_adaptor<std::string> >
{
private:
typedef Arabica::XPath::DefaultVariableCompileTimeResolver<std::string, Arabica::default_string_adaptor<std::string> > 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<std::string> xpath_expression(const std::string& expr) const { return xpath_.compile_expr(expr); }
Arabica::XPath::XPathExpressionPtr<std::string> xpath_expression_no_variables(const std::string& expr) const
{
Disallow variables(variables_allowed_);
return xpath_expression(expr);
} // xpath_expression_no_variables
std::vector<Arabica::XPath::MatchExpr<std::string> > xpath_match(const std::string& match) const
{
DisallowCurrent guard(current_allowed_);
Disallow current(current_allowed_);
return xpath_.compile_match(match);
} // xpath_match
std::vector<Arabica::XPath::MatchExpr<std::string> > xpath_match_no_variables(const std::string& match) const
{
Disallow variables(variables_allowed_);
return xpath_match(match);
} // xpath_match_no_variables
Arabica::XPath::XPathExpressionPtr<std::string> 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<std::string, Arabica::default_string_adaptor<std::string> >*
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<std::string>* 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<std::string> xpath_;
std::stack<SAX::DefaultHandler<std::string>*> 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