Commit 01b68c51 authored by Georgi Kodinov's avatar Georgi Kodinov

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.
parent ae154449
...@@ -1144,5 +1144,23 @@ SELECT UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0); ...@@ -1144,5 +1144,23 @@ SELECT UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0);
UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0) UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0)
NULL NULL
# #
# Bug#12375190: UPDATEXML CRASHES ON SIMPLE INPUTS
#
SELECT UPDATEXML('','(a)/a','');
UPDATEXML('','(a)/a','')
SELECT UPDATEXML('<a><a>x</a></a>','(a)/a','<b />');
UPDATEXML('<a><a>x</a></a>','(a)/a','<b />')
<a><b /></a>
SELECT UPDATEXML('<a><c><a>x</a></c></a>','(a)/a','<b />');
UPDATEXML('<a><c><a>x</a></c></a>','(a)/a','<b />')
<a><c><a>x</a></c></a>
SELECT UPDATEXML('<a><c><a>x</a></c></a>','(a)//a','<b />');
UPDATEXML('<a><c><a>x</a></c></a>','(a)//a','<b />')
<a><c><b /></c></a>
SELECT ExtractValue('<a><a>aa</a><b>bb</b></a>','(a)/a|(a)/b');
ExtractValue('<a><a>aa</a><b>bb</b></a>','(a)/a|(a)/b')
aa bb
#
# End of 5.5 tests # End of 5.5 tests
# #
...@@ -664,6 +664,15 @@ SELECT ExtractValue(CONVERT('<\"', BINARY(10)), 1); ...@@ -664,6 +664,15 @@ SELECT ExtractValue(CONVERT('<\"', BINARY(10)), 1);
SET NAMES latin1; SET NAMES latin1;
SELECT UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0); SELECT UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0);
--echo #
--echo # Bug#12375190: UPDATEXML CRASHES ON SIMPLE INPUTS
--echo #
SELECT UPDATEXML('','(a)/a','');
SELECT UPDATEXML('<a><a>x</a></a>','(a)/a','<b />');
SELECT UPDATEXML('<a><c><a>x</a></c></a>','(a)/a','<b />');
SELECT UPDATEXML('<a><c><a>x</a></c></a>','(a)//a','<b />');
SELECT ExtractValue('<a><a>aa</a><b>bb</b></a>','(a)/a|(a)/b');
--echo # --echo #
--echo # End of 5.5 tests --echo # End of 5.5 tests
--echo # --echo #
...@@ -1973,6 +1973,9 @@ static int my_xpath_parse_UnionExpr(MY_XPATH *xpath) ...@@ -1973,6 +1973,9 @@ static int my_xpath_parse_UnionExpr(MY_XPATH *xpath)
static int static int
my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath) my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath)
{ {
Item *context= xpath->context;
int rc;
if (!my_xpath_parse_FilterExpr(xpath)) if (!my_xpath_parse_FilterExpr(xpath))
return 0; return 0;
...@@ -1986,8 +1989,22 @@ my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath) ...@@ -1986,8 +1989,22 @@ my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath)
return 0; 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) static int my_xpath_parse_PathExpr(MY_XPATH *xpath)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment