Commit 033db2d0 authored by unknown's avatar unknown

Bug #20778: strange characters in warning message 1366 when called in SP

The function receives an exactly-sized buffer (not a C NUL-terminated string)
and passes it into a printf function to be interpreted with "%s".

Instead, create an intermediate String object, and copy the data into it, 
and pass in a pointer to the String's NUL-terminated buffer.


mysql-test/r/warnings.result:
  Test that warnings do not read outside its intended memory space.
mysql-test/t/warnings.test:
  Test that warnings do not read outside its intended memory space.
sql/field.cc:
  Create a new String object and use a pointer to its data instead of the 
  exactly-sized buffer to be interpreted as a C string deep within the 
  errmsg.txt list via printf.
parent 131d94f5
...@@ -243,3 +243,59 @@ a ...@@ -243,3 +243,59 @@ a
select * from t1 limit 0, 0; select * from t1 limit 0, 0;
a a
drop table t1; drop table t1;
End of 4.1 tests
CREATE TABLE t1( f1 CHAR(20) );
CREATE TABLE t2( f1 CHAR(20), f2 CHAR(25) );
CREATE TABLE t3( f1 CHAR(20), f2 CHAR(25), f3 DATE );
INSERT INTO t1 VALUES ( 'a`' );
INSERT INTO t2 VALUES ( 'a`', 'a`' );
INSERT INTO t3 VALUES ( 'a`', 'a`', '1000-01-1' );
DROP PROCEDURE IF EXISTS sp1;
Warnings:
Note 1305 PROCEDURE sp1 does not exist
DROP PROCEDURE IF EXISTS sp2;
Warnings:
Note 1305 PROCEDURE sp2 does not exist
DROP PROCEDURE IF EXISTS sp3;
Warnings:
Note 1305 PROCEDURE sp3 does not exist
CREATE PROCEDURE sp1()
BEGIN
DECLARE x NUMERIC ZEROFILL;
SELECT f1 INTO x FROM t1 LIMIT 1;
END//
CREATE PROCEDURE sp2()
BEGIN
DECLARE x NUMERIC ZEROFILL;
SELECT f1 INTO x FROM t2 LIMIT 1;
END//
CREATE PROCEDURE sp3()
BEGIN
DECLARE x NUMERIC ZEROFILL;
SELECT f1 INTO x FROM t3 LIMIT 1;
END//
CALL sp1();
Warnings:
Warning 1366 Incorrect decimal value: 'a`' for column 'x' at row 1
CALL sp2();
Warnings:
Warning 1366 Incorrect decimal value: 'a`' for column 'x' at row 1
CALL sp3();
Warnings:
Warning 1366 Incorrect decimal value: 'a`' for column 'x' at row 1
DROP PROCEDURE IF EXISTS sp1;
CREATE PROCEDURE sp1()
BEGIN
declare x numeric unsigned zerofill;
SELECT f1 into x from t2 limit 1;
END//
CALL sp1();
Warnings:
Warning 1366 Incorrect decimal value: 'a`' for column 'x' at row 1
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP PROCEDURE sp1;
DROP PROCEDURE sp2;
DROP PROCEDURE sp3;
End of 5.0 tests
...@@ -156,4 +156,60 @@ select * from t1 limit 1, 0; ...@@ -156,4 +156,60 @@ select * from t1 limit 1, 0;
select * from t1 limit 0, 0; select * from t1 limit 0, 0;
drop table t1; drop table t1;
# End of 4.1 tests --echo End of 4.1 tests
#
# Bug#20778: strange characters in warning message 1366 when called in SP
#
let $engine_type= innodb;
CREATE TABLE t1( f1 CHAR(20) );
CREATE TABLE t2( f1 CHAR(20), f2 CHAR(25) );
CREATE TABLE t3( f1 CHAR(20), f2 CHAR(25), f3 DATE );
INSERT INTO t1 VALUES ( 'a`' );
INSERT INTO t2 VALUES ( 'a`', 'a`' );
INSERT INTO t3 VALUES ( 'a`', 'a`', '1000-01-1' );
DROP PROCEDURE IF EXISTS sp1;
DROP PROCEDURE IF EXISTS sp2;
DROP PROCEDURE IF EXISTS sp3;
delimiter //;
CREATE PROCEDURE sp1()
BEGIN
DECLARE x NUMERIC ZEROFILL;
SELECT f1 INTO x FROM t1 LIMIT 1;
END//
CREATE PROCEDURE sp2()
BEGIN
DECLARE x NUMERIC ZEROFILL;
SELECT f1 INTO x FROM t2 LIMIT 1;
END//
CREATE PROCEDURE sp3()
BEGIN
DECLARE x NUMERIC ZEROFILL;
SELECT f1 INTO x FROM t3 LIMIT 1;
END//
delimiter ;//
CALL sp1();
CALL sp2();
CALL sp3();
DROP PROCEDURE IF EXISTS sp1;
delimiter //;
CREATE PROCEDURE sp1()
BEGIN
declare x numeric unsigned zerofill;
SELECT f1 into x from t2 limit 1;
END//
delimiter ;//
CALL sp1();
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP PROCEDURE sp1;
DROP PROCEDURE sp2;
DROP PROCEDURE sp3;
--echo End of 5.0 tests
...@@ -2316,11 +2316,16 @@ int Field_new_decimal::store(const char *from, uint length, ...@@ -2316,11 +2316,16 @@ int Field_new_decimal::store(const char *from, uint length,
from, length, charset, &decimal_value)) && from, length, charset, &decimal_value)) &&
table->in_use->abort_on_warning) table->in_use->abort_on_warning)
{ {
/* Because "from" is not NUL-terminated and we use %s in the ER() */
String from_as_str;
from_as_str.copy(from, length, &my_charset_bin);
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_ERROR, push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
"decimal", from, field_name, "decimal", from_as_str.c_ptr(), field_name,
(ulong) table->in_use->row_count); (ulong) table->in_use->row_count);
DBUG_RETURN(err); DBUG_RETURN(err);
} }
...@@ -2333,14 +2338,21 @@ int Field_new_decimal::store(const char *from, uint length, ...@@ -2333,14 +2338,21 @@ int Field_new_decimal::store(const char *from, uint length,
set_value_on_overflow(&decimal_value, decimal_value.sign()); set_value_on_overflow(&decimal_value, decimal_value.sign());
break; break;
case E_DEC_BAD_NUM: case E_DEC_BAD_NUM:
{
/* Because "from" is not NUL-terminated and we use %s in the ER() */
String from_as_str;
from_as_str.copy(from, length, &my_charset_bin);
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
"decimal", from, field_name, "decimal", from_as_str.c_ptr(), field_name,
(ulong) table->in_use->row_count); (ulong) table->in_use->row_count);
my_decimal_set_zero(&decimal_value); my_decimal_set_zero(&decimal_value);
break; break;
} }
}
#ifndef DBUG_OFF #ifndef DBUG_OFF
char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; char dbug_buff[DECIMAL_MAX_STR_LENGTH+1];
......
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