summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/xml.result18
-rw-r--r--mysql-test/t/xml.test9
-rw-r--r--sql/item_xmlfunc.cc21
3 files changed, 46 insertions, 2 deletions
diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result
index 8ca9ab84bf7..30aa77ddf37 100644
--- a/mysql-test/r/xml.result
+++ b/mysql-test/r/xml.result
@@ -1144,5 +1144,23 @@ SELECT UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0);
UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0)
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
#
diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test
index 89c0b8992b1..b36bd2067cc 100644
--- a/mysql-test/t/xml.test
+++ b/mysql-test/t/xml.test
@@ -665,5 +665,14 @@ SET NAMES latin1;
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 # End of 5.5 tests
--echo #
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)
{