From bcc72ad04f2df6aea27550d6389c39d03a29691e Mon Sep 17 00:00:00 2001
From: "bar@mysql.com" <>
Date: Tue, 28 Feb 2006 13:59:16 +0400
Subject: [PATCH] Bug#16313 XML: extractvalue() ignores '!' in names
xml.result, xml.test: Adding test case. item_xmlfunc.cc: Fixed that the
"!" character written at the end was ignored.
Now if we try to scan "!=", and if "!" is not
followed by "=", we rollback lex scanner back
to "!" token, so the parser will start to check
the next rule from the "!" character again.
Previously parser started from the next character,
which was EOF in the example in xml.test,
which led to query being successfully parsed,
instead of producing a syntax error.
---
mysql-test/r/xml.result | 2 ++
mysql-test/t/xml.test | 6 ++++++
sql/item_xmlfunc.cc | 13 +++++++++++--
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result
index b4121ae473d..3ed3df546d1 100644
--- a/mysql-test/r/xml.result
+++ b/mysql-test/r/xml.result
@@ -544,3 +544,5 @@ extractvalue('aB','a|/b')
a
select extractvalue('A','/');
ERROR HY000: XPATH syntax error: '>'
+select extractvalue('bb!','//b!');
+ERROR HY000: XPATH syntax error: '!'
diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test
index 0e24692f0fa..e69ab5ee58b 100644
--- a/mysql-test/t/xml.test
+++ b/mysql-test/t/xml.test
@@ -237,3 +237,9 @@ select extractvalue('aB','a|/b');
#
--error 1105
select extractvalue('A','/');
+
+#
+# Bug#16313 XML: extractvalue() ignores '!' in names
+#
+--error 1105
+select extractvalue('bb!','//b!');
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index d86b6acfc56..aad9e12f6c5 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -1976,8 +1976,17 @@ static int my_xpath_parse_AndExpr(MY_XPATH *xpath)
*/
static int my_xpath_parse_ne(MY_XPATH *xpath)
{
- return my_xpath_parse_term(xpath, MY_XPATH_LEX_EXCL) &&
- my_xpath_parse_term(xpath, MY_XPATH_LEX_EQ);
+ MY_XPATH_LEX prevtok= xpath->prevtok;
+ if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_EXCL))
+ return 0;
+ if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_EQ))
+ {
+ /* Unget the exclamation mark */
+ xpath->lasttok= xpath->prevtok;
+ xpath->prevtok= prevtok;
+ return 0;
+ }
+ return 1;
}
static int my_xpath_parse_EqualityOperator(MY_XPATH *xpath)
{