mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Bug#38469 invalid memory read and/or crash with utf8 text field, stored procedure, uservar
A stored procedure involving substrings could crash the server on certain platforms because of invalid memory reads. During storing the new blob-field value, the cached value's address range overlapped that of the new field value. This caused problems when the cached value storage was reallocated to provide access for a new characater set representation. The patch checks the address ranges, and if they overlap, the new field value is copied to a new storage before it is converted to the new character set. mysql-test/r/sp.result: Added result set mysql-test/t/sp.test: Added test case sql/field.cc: The source and destination address ranges of a character conversion must not overlap or the 'from' address will be invalidated as the temporary value- object is re-allocated to fit the new character set. sql/field.h: Added comments
This commit is contained in:
@ -6662,6 +6662,16 @@ drop procedure p1;
|
|||||||
drop function f1;
|
drop function f1;
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
drop procedure if exists `p2` $
|
||||||
|
create procedure `p2`(in `a` text charset utf8)
|
||||||
|
begin
|
||||||
|
declare `pos` int default 1;
|
||||||
|
declare `str` text charset utf8;
|
||||||
|
set `str` := `a`;
|
||||||
|
select substr(`str`, `pos`+ 1 ) into `str`;
|
||||||
|
end $
|
||||||
|
call `p2`('s s s s s s');
|
||||||
|
drop procedure `p2`;
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# -- End of 5.0 tests
|
# -- End of 5.0 tests
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
@ -7818,6 +7818,24 @@ drop function f1;
|
|||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#38469 invalid memory read and/or crash with utf8 text field, stored procedure, uservar
|
||||||
|
#
|
||||||
|
delimiter $;
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists `p2` $
|
||||||
|
--enable_warnings
|
||||||
|
create procedure `p2`(in `a` text charset utf8)
|
||||||
|
begin
|
||||||
|
declare `pos` int default 1;
|
||||||
|
declare `str` text charset utf8;
|
||||||
|
set `str` := `a`;
|
||||||
|
select substr(`str`, `pos`+ 1 ) into `str`;
|
||||||
|
end $
|
||||||
|
delimiter ;$
|
||||||
|
call `p2`('s s s s s s');
|
||||||
|
drop procedure `p2`;
|
||||||
|
|
||||||
--echo # ------------------------------------------------------------------
|
--echo # ------------------------------------------------------------------
|
||||||
--echo # -- End of 5.0 tests
|
--echo # -- End of 5.0 tests
|
||||||
--echo # ------------------------------------------------------------------
|
--echo # ------------------------------------------------------------------
|
||||||
|
12
sql/field.cc
12
sql/field.cc
@ -6992,8 +6992,18 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (from == value.ptr())
|
/*
|
||||||
|
If the 'from' address is in the range of the temporary 'value'-
|
||||||
|
object we need to copy the content to a different location or it will be
|
||||||
|
invalidated when the 'value'-object is reallocated to make room for
|
||||||
|
the new character set.
|
||||||
|
*/
|
||||||
|
if (from >= value.ptr() && from <= value.ptr()+value.length())
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
If content of the 'from'-address is cached in the 'value'-object
|
||||||
|
it is possible that the content needs a character conversion.
|
||||||
|
*/
|
||||||
uint32 dummy_offset;
|
uint32 dummy_offset;
|
||||||
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
|
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
|
||||||
{
|
{
|
||||||
|
10
sql/field.h
10
sql/field.h
@ -1213,8 +1213,16 @@ public:
|
|||||||
|
|
||||||
class Field_blob :public Field_longstr {
|
class Field_blob :public Field_longstr {
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
The number of bytes used to represent the length of the blob.
|
||||||
|
*/
|
||||||
uint packlength;
|
uint packlength;
|
||||||
String value; // For temporaries
|
|
||||||
|
/**
|
||||||
|
The 'value'-object is a cache fronting the storage engine.
|
||||||
|
*/
|
||||||
|
String value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
||||||
enum utype unireg_check_arg, const char *field_name_arg,
|
enum utype unireg_check_arg, const char *field_name_arg,
|
||||||
|
Reference in New Issue
Block a user