summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bar@mysql.com>2006-04-17 14:40:25 +0500
committerunknown <bar@mysql.com>2006-04-17 14:40:25 +0500
commit3010775ed19b6fbbbc2837e5ed8b377266c5533a (patch)
treead61da58fe13bee1f57a91497b08bc491cec4c3d
parent3ef014862b0a8c374e10c6dd43bd90634bc1ba23 (diff)
downloadmariadb-git-3010775ed19b6fbbbc2837e5ed8b377266c5533a.tar.gz
Bug#18201: XML: ExtractValue works even if the xml
fragment is not well-formed xml Problem: - ExtractValue silently returned NULL if a wrong XML value is passed. - In some cases "unexpected END-OF-INPUT" error was not detected, and a non-NULL result could be returned for a bad XML value. Fix: - Adding warning messages, to make user aware why NULL was returned. - Missing "unexpected END-OF-INPUT" error is reported now. mysql-test/r/xml.result: - Fixing XML systax error in old test - Adding test cases. mysql-test/t/xml.test: - Fixing XML systax error in old test - Adding test cases. sql/item_xmlfunc.cc: Produce warning in case of XML systax error, instead of silentrly returning NULL. strings/xml.c: - Making error messages better looking and clearer: It is important because now they're seen in SHOW WARNINGS (previously they were used only for debugging purposes). - Adding "unexpected END-OF-INPUT" error if after scanning closing tag for the root element some input is left (previously this error was ignored in a mistake).
-rw-r--r--mysql-test/r/xml.result32
-rw-r--r--mysql-test/t/xml.test13
-rw-r--r--sql/item_xmlfunc.cc12
-rw-r--r--strings/xml.c27
4 files changed, 73 insertions, 11 deletions
diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result
index 7e44673dd78..15daf7bb9b5 100644
--- a/mysql-test/r/xml.result
+++ b/mysql-test/r/xml.result
@@ -132,7 +132,7 @@ xb1 xc1
SELECT extractValue(@xml,'/a//@x[2]');
extractValue(@xml,'/a//@x[2]')
xb2 xc2
-SET @xml='<a><b>b1</b><b>b2</b><c><b>c1b1</b><b>c1b2</b></c><c><b>c2b1</c></b>/a>';
+SET @xml='<a><b>b1</b><b>b2</b><c><b>c1b1</b><b>c1b2</b></c><c><b>c2b1</c></b></a>';
SELECT extractValue(@xml,'//b[1]');
extractValue(@xml,'//b[1]')
b1 c1b1 c2b1
@@ -612,6 +612,36 @@ extractvalue('<a>Jack</a>' collate latin1_bin,'/a[contains(../a,"j")]')
select ExtractValue('<tag1><![CDATA[test]]></tag1>','/tag1');
ExtractValue('<tag1><![CDATA[test]]></tag1>','/tag1')
test
+select extractValue('<a>a','/a');
+extractValue('<a>a','/a')
+NULL
+Warnings:
+Warning 1504 Incorrect XML value: 'parse error at line 1 pos 5: unexpected END-OF-INPUT'
+select extractValue('<a>a<','/a');
+extractValue('<a>a<','/a')
+NULL
+Warnings:
+Warning 1504 Incorrect XML value: 'parse error at line 1 pos 6: END-OF-INPUT unexpected (ident or '/' wanted)'
+select extractValue('<a>a</','/a');
+extractValue('<a>a</','/a')
+NULL
+Warnings:
+Warning 1504 Incorrect XML value: 'parse error at line 1 pos 7: END-OF-INPUT unexpected (ident wanted)'
+select extractValue('<a>a</a','/a');
+extractValue('<a>a</a','/a')
+NULL
+Warnings:
+Warning 1504 Incorrect XML value: 'parse error at line 1 pos 8: END-OF-INPUT unexpected ('>' wanted)'
+select extractValue('<a>a</a></b>','/a');
+extractValue('<a>a</a></b>','/a')
+NULL
+Warnings:
+Warning 1504 Incorrect XML value: 'parse error at line 1 pos 12: '</b>' unexpected (END-OF-INPUT wanted)'
+select extractValue('<a b=>a</a>','/a');
+extractValue('<a b=>a</a>','/a')
+NULL
+Warnings:
+Warning 1504 Incorrect XML value: 'parse error at line 1 pos 7: '>' unexpected (ident or string wanted)'
select extractValue('<e>1</e>','position()');
ERROR HY000: XPATH syntax error: ''
select extractValue('<e>1</e>','last()');
diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test
index 8ed623883b6..af509a2f45e 100644
--- a/mysql-test/t/xml.test
+++ b/mysql-test/t/xml.test
@@ -53,7 +53,7 @@ SELECT extractValue(@xml,'/a//@x');
SELECT extractValue(@xml,'/a//@x[1]');
SELECT extractValue(@xml,'/a//@x[2]');
-SET @xml='<a><b>b1</b><b>b2</b><c><b>c1b1</b><b>c1b2</b></c><c><b>c2b1</c></b>/a>';
+SET @xml='<a><b>b1</b><b>b2</b><c><b>c1b1</b><b>c1b2</b></c><c><b>c2b1</c></b></a>';
SELECT extractValue(@xml,'//b[1]');
SELECT extractValue(@xml,'/descendant::b[1]');
@@ -285,6 +285,17 @@ select extractvalue('<a>Jack</a>' collate latin1_bin,'/a[contains(../a,"j")]');
select ExtractValue('<tag1><![CDATA[test]]></tag1>','/tag1');
#
+# Bug#18201: XML: ExtractValue works even if the xml fragment
+# is not well-formed xml
+#
+select extractValue('<a>a','/a');
+select extractValue('<a>a<','/a');
+select extractValue('<a>a</','/a');
+select extractValue('<a>a</a','/a');
+select extractValue('<a>a</a></b>','/a');
+select extractValue('<a b=>a</a>','/a');
+
+#
# Bug #18171 XML: ExtractValue: the XPath position()
# function crashes the server!
#
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 71900c26c2d..6bbbf67e074 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -2563,7 +2563,17 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf)
xml_enter(&p, raw_xml->ptr(), 0);
/* Execute XML parser */
- rc= my_xml_parse(&p, raw_xml->ptr(), raw_xml->length());
+ if ((rc= my_xml_parse(&p, raw_xml->ptr(), raw_xml->length())) != MY_XML_OK)
+ {
+ char buf[128];
+ my_snprintf(buf, sizeof(buf)-1, "parse error at line %d pos %d: %s",
+ my_xml_error_lineno(&p) + 1,
+ my_xml_error_pos(&p) + 1,
+ my_xml_error_string(&p));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_VALUE,
+ ER(ER_WRONG_VALUE), "XML", buf);
+ }
my_xml_parser_free(&p);
return rc == MY_XML_OK ? parsed_xml_buf : 0;
diff --git a/strings/xml.c b/strings/xml.c
index 4c09e85604d..76fdd07f25e 100644
--- a/strings/xml.c
+++ b/strings/xml.c
@@ -43,7 +43,7 @@ static const char *lex2str(int lex)
{
switch(lex)
{
- case MY_XML_EOF: return "EOF";
+ case MY_XML_EOF: return "END-OF-INPUT";
case MY_XML_STRING: return "STRING";
case MY_XML_IDENT: return "IDENT";
case MY_XML_CDATA: return "CDATA";
@@ -195,8 +195,13 @@ static int my_xml_leave(MY_XML_PARSER *p, const char *str, uint slen)
if (str && (slen != glen))
{
mstr(s,str,sizeof(s)-1,slen);
- mstr(g,e+1,sizeof(g)-1,glen),
- sprintf(p->errstr,"'</%s>' unexpected ('</%s>' wanted)",s,g);
+ if (glen)
+ {
+ mstr(g,e+1,sizeof(g)-1,glen),
+ sprintf(p->errstr,"'</%s>' unexpected ('</%s>' wanted)",s,g);
+ }
+ else
+ sprintf(p->errstr,"'</%s>' unexpected (END-OF-INPUT wanted)", s);
return MY_XML_ERROR;
}
@@ -247,7 +252,7 @@ int my_xml_parse(MY_XML_PARSER *p,const char *str, uint len)
{
if (MY_XML_IDENT != (lex=my_xml_scan(p,&a)))
{
- sprintf(p->errstr,"1: %s unexpected (ident wanted)",lex2str(lex));
+ sprintf(p->errstr,"%s unexpected (ident wanted)",lex2str(lex));
return MY_XML_ERROR;
}
if (MY_XML_OK != my_xml_leave(p,a.beg,(uint) (a.end-a.beg)))
@@ -275,7 +280,7 @@ int my_xml_parse(MY_XML_PARSER *p,const char *str, uint len)
}
else
{
- sprintf(p->errstr,"3: %s unexpected (ident or '/' wanted)",
+ sprintf(p->errstr,"%s unexpected (ident or '/' wanted)",
lex2str(lex));
return MY_XML_ERROR;
}
@@ -297,7 +302,7 @@ int my_xml_parse(MY_XML_PARSER *p,const char *str, uint len)
}
else
{
- sprintf(p->errstr,"4: %s unexpected (ident or string wanted)",
+ sprintf(p->errstr,"%s unexpected (ident or string wanted)",
lex2str(lex));
return MY_XML_ERROR;
}
@@ -325,7 +330,7 @@ gt:
{
if (lex != MY_XML_QUESTION)
{
- sprintf(p->errstr,"6: %s unexpected ('?' wanted)",lex2str(lex));
+ sprintf(p->errstr,"%s unexpected ('?' wanted)",lex2str(lex));
return MY_XML_ERROR;
}
if (MY_XML_OK != my_xml_leave(p,NULL,0))
@@ -341,7 +346,7 @@ gt:
if (lex != MY_XML_GT)
{
- sprintf(p->errstr,"5: %s unexpected ('>' wanted)",lex2str(lex));
+ sprintf(p->errstr,"%s unexpected ('>' wanted)",lex2str(lex));
return MY_XML_ERROR;
}
}
@@ -359,6 +364,12 @@ gt:
}
}
}
+
+ if (p->attr[0])
+ {
+ sprintf(p->errstr,"unexpected END-OF-INPUT");
+ return MY_XML_ERROR;
+ }
return MY_XML_OK;
}