Commit aa668865 authored by Alexander Barkov's avatar Alexander Barkov

Bug#57257 Replace(ExtractValue(...)) causes MySQL crash

Bug#57820 extractvalue crashes

Problem: ExtractValue and Replace crashed in some cases
due to invalid handling of empty and NULL arguments.

Per file comments:

  @mysql-test/r/ctype_ujis.result
  @mysql-test/r/xml.result
  @mysql-test/t/ctype_ujis.test
  @mysql-test/t/xml.test
  Adding tests

  @sql/item_strfunc.cc
  Make sure Item_func_replace::val_str safely handles empty strings.

  @sql/item_xmlfunc.cc
  set null_value if nodeset_func returned NULL,
  which is possible when the second argument is an
  unset user variable.
parent 9f71cfc0
...@@ -2374,6 +2374,16 @@ hex(convert(_latin1 0xA4A2 using ujis)) hex(c2) ...@@ -2374,6 +2374,16 @@ hex(convert(_latin1 0xA4A2 using ujis)) hex(c2)
DROP PROCEDURE sp1; DROP PROCEDURE sp1;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
#
# Bug#57257 Replace(ExtractValue(...)) causes MySQL crash
#
SET NAMES utf8;
SELECT CONVERT(REPLACE(EXPORT_SET('a','a','a','','a'),'00','') USING ujis);
CONVERT(REPLACE(EXPORT_SET('a','a','a','','a'),'00','') USING ujis)
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'a'
Warning 1292 Truncated incorrect INTEGER value: 'a'
set names default; set names default;
set character_set_database=default; set character_set_database=default;
set character_set_server=default; set character_set_server=default;
...@@ -1093,4 +1093,17 @@ Warnings: ...@@ -1093,4 +1093,17 @@ Warnings:
Warning 1525 Incorrect XML value: 'parse error at line 1 pos 23: unexpected END-OF-INPUT' Warning 1525 Incorrect XML value: 'parse error at line 1 pos 23: unexpected END-OF-INPUT'
Warning 1525 Incorrect XML value: 'parse error at line 1 pos 23: unexpected END-OF-INPUT' Warning 1525 Incorrect XML value: 'parse error at line 1 pos 23: unexpected END-OF-INPUT'
DROP TABLE t1; DROP TABLE t1;
#
# Bug#57257 Replace(ExtractValue(...)) causes MySQL crash
#
SET NAMES utf8;
SELECT REPLACE(EXTRACTVALUE('1', '/a'),'ds','');
REPLACE(EXTRACTVALUE('1', '/a'),'ds','')
#
# Bug #57820 extractvalue crashes
#
SELECT AVG(DISTINCT EXTRACTVALUE((''),('$@k')));
AVG(DISTINCT EXTRACTVALUE((''),('$@k')))
NULL
End of 5.1 tests End of 5.1 tests
...@@ -1209,6 +1209,13 @@ DROP PROCEDURE sp1; ...@@ -1209,6 +1209,13 @@ DROP PROCEDURE sp1;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
--echo #
--echo # Bug#57257 Replace(ExtractValue(...)) causes MySQL crash
--echo #
SET NAMES utf8;
SELECT CONVERT(REPLACE(EXPORT_SET('a','a','a','','a'),'00','') USING ujis);
set names default; set names default;
set character_set_database=default; set character_set_database=default;
set character_set_server=default; set character_set_server=default;
...@@ -617,4 +617,15 @@ FROM t1 ORDER BY t1.id; ...@@ -617,4 +617,15 @@ FROM t1 ORDER BY t1.id;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug#57257 Replace(ExtractValue(...)) causes MySQL crash
--echo #
SET NAMES utf8;
SELECT REPLACE(EXTRACTVALUE('1', '/a'),'ds','');
--echo #
--echo # Bug #57820 extractvalue crashes
--echo #
SELECT AVG(DISTINCT EXTRACTVALUE((''),('$@k')));
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -904,9 +904,15 @@ String *Item_func_replace::val_str(String *str) ...@@ -904,9 +904,15 @@ String *Item_func_replace::val_str(String *str)
search=res2->ptr(); search=res2->ptr();
search_end=search+from_length; search_end=search+from_length;
redo: redo:
DBUG_ASSERT(res->ptr() || !offset);
ptr=res->ptr()+offset; ptr=res->ptr()+offset;
strend=res->ptr()+res->length(); strend=res->ptr()+res->length();
end=strend-from_length+1; /*
In some cases val_str() can return empty string
with ptr() == NULL and length() == 0.
Let's check strend to avoid overflow.
*/
end= strend ? strend - from_length + 1 : NULL;
while (ptr < end) while (ptr < end)
{ {
if (*ptr == *search) if (*ptr == *search)
......
...@@ -2790,12 +2790,12 @@ String *Item_func_xml_extractvalue::val_str(String *str) ...@@ -2790,12 +2790,12 @@ String *Item_func_xml_extractvalue::val_str(String *str)
null_value= 0; null_value= 0;
if (!nodeset_func || if (!nodeset_func ||
!(res= args[0]->val_str(str)) || !(res= args[0]->val_str(str)) ||
!parse_xml(res, &pxml)) !parse_xml(res, &pxml) ||
!(res= nodeset_func->val_str(&tmp_value)))
{ {
null_value= 1; null_value= 1;
return 0; return 0;
} }
res= nodeset_func->val_str(&tmp_value);
return res; return res;
} }
......
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