summaryrefslogtreecommitdiff
path: root/sql/item_xmlfunc.cc
diff options
context:
space:
mode:
authorGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2011-05-03 10:48:24 +0300
committerGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2011-05-03 10:48:24 +0300
commitd33bed3c23259bd4a45d909ffa26b88176a02978 (patch)
treedaf416307940106fbee129775b57aa569d64557a /sql/item_xmlfunc.cc
parent1019b95877bd1a8f581e58a9f2d52ec52d23e5b7 (diff)
downloadmariadb-git-d33bed3c23259bd4a45d909ffa26b88176a02978.tar.gz
Bug #12375190: UPDATEXML CRASHES ON SIMPLE INPUTS
The XPATH implementation was not handling correctly the XPATH production #19 (http://www.w3.org/TR/1999/REC-xpath-19991116/#node-sets), namely PathExpr ::= | FilterExpr '/' RelativeLocationPath | FilterExpr '//' RelativeLocationPath It was lacking context for the RelativeLocationPath and it was just ignoring the second slash instead of treating it as a different axis specifier. Fixed the above two problems and added a test case.
Diffstat (limited to 'sql/item_xmlfunc.cc')
-rw-r--r--sql/item_xmlfunc.cc21
1 files changed, 19 insertions, 2 deletions
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 49d18b1bb0f..531b9e11cb5 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -1973,6 +1973,9 @@ static int my_xpath_parse_UnionExpr(MY_XPATH *xpath)
static int
my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath)
{
+ Item *context= xpath->context;
+ int rc;
+
if (!my_xpath_parse_FilterExpr(xpath))
return 0;
@@ -1986,8 +1989,22 @@ my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath)
return 0;
}
- my_xpath_parse_term(xpath, MY_XPATH_LEX_SLASH);
- return my_xpath_parse_RelativeLocationPath(xpath);
+ /*
+ The context for the next relative path is the nodeset
+ returned by FilterExpr
+ */
+ xpath->context= xpath->item;
+
+ /* treat double slash (//) as /descendant-or-self::node()/ */
+ if (my_xpath_parse_term(xpath, MY_XPATH_LEX_SLASH))
+ xpath->context= new Item_nodeset_func_descendantbyname(xpath->context,
+ "*", 1, xpath->pxml, 1);
+ rc= my_xpath_parse_RelativeLocationPath(xpath);
+
+ /* push back the context and restore the item */
+ xpath->item= xpath->context;
+ xpath->context= context;
+ return rc;
}
static int my_xpath_parse_PathExpr(MY_XPATH *xpath)
{