Bug #59241 invalid memory read in do_div_mod with doubly assigned variables
Fix: copy my_decimal by value, to avoid dangling pointers. mysql-test/r/func_math.result: New test case. mysql-test/t/func_math.test: New test case. sql/item_cmpfunc.cc: No need to call fix_buffer_pointer() anymore. sql/item_func.cc: Copy my_decimal by value, to avoid dangling pointers. sql/my_decimal.h: Implement proper copy constructor and assignment operator for my_decimal. sql/sql_analyse.cc: No need to call fix_buffer_pointer() anymore. strings/decimal.c: Remove #line directive: it messes up TAGS and it confuses gdb when debugging.
This commit is contained in:
parent
ff2b529918
commit
7bf234032a
@ -641,3 +641,12 @@ INSERT INTO t1 (SELECT -pi());
|
|||||||
Warnings:
|
Warnings:
|
||||||
Warning 1265 Data truncated for column 'a' at row 1
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug #59241 invalid memory read
|
||||||
|
# in do_div_mod with doubly assigned variables
|
||||||
|
#
|
||||||
|
SELECT ((@a:=@b:=1.0) div (@b:=@a:=get_format(datetime, 'usa')));
|
||||||
|
((@a:=@b:=1.0) div (@b:=@a:=get_format(datetime, 'usa')))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1366 Incorrect decimal value: '' for column '' at row -1
|
||||||
|
@ -489,3 +489,9 @@ as foo;
|
|||||||
CREATE TABLE t1(a char(0));
|
CREATE TABLE t1(a char(0));
|
||||||
INSERT INTO t1 (SELECT -pi());
|
INSERT INTO t1 (SELECT -pi());
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #59241 invalid memory read
|
||||||
|
--echo # in do_div_mod with doubly assigned variables
|
||||||
|
--echo #
|
||||||
|
SELECT ((@a:=@b:=1.0) div (@b:=@a:=get_format(datetime, 'usa')));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -2086,7 +2086,6 @@ void Item_func_interval::fix_length_and_dec()
|
|||||||
if (dec != &range->dec)
|
if (dec != &range->dec)
|
||||||
{
|
{
|
||||||
range->dec= *dec;
|
range->dec= *dec;
|
||||||
range->dec.fix_buffer_pointer();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -1581,24 +1581,22 @@ longlong Item_func_int_div::val_int()
|
|||||||
if (args[0]->result_type() != INT_RESULT ||
|
if (args[0]->result_type() != INT_RESULT ||
|
||||||
args[1]->result_type() != INT_RESULT)
|
args[1]->result_type() != INT_RESULT)
|
||||||
{
|
{
|
||||||
my_decimal value0, value1, tmp;
|
my_decimal tmp;
|
||||||
my_decimal *val0, *val1;
|
my_decimal val0= *args[0]->val_decimal(&tmp);
|
||||||
longlong res;
|
my_decimal val1= *args[1]->val_decimal(&tmp);
|
||||||
int err;
|
|
||||||
|
|
||||||
val0= args[0]->val_decimal(&value0);
|
|
||||||
val1= args[1]->val_decimal(&value1);
|
|
||||||
if ((null_value= (args[0]->null_value || args[1]->null_value)))
|
if ((null_value= (args[0]->null_value || args[1]->null_value)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
int err;
|
||||||
if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, &tmp,
|
if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, &tmp,
|
||||||
val0, val1, 0)) > 3)
|
&val0, &val1, 0)) > 3)
|
||||||
{
|
{
|
||||||
if (err == E_DEC_DIV_ZERO)
|
if (err == E_DEC_DIV_ZERO)
|
||||||
signal_divide_by_null();
|
signal_divide_by_null();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
longlong res;
|
||||||
if (my_decimal2int(E_DEC_FATAL_ERROR, &tmp, unsigned_flag, &res) &
|
if (my_decimal2int(E_DEC_FATAL_ERROR, &tmp, unsigned_flag, &res) &
|
||||||
E_DEC_OVERFLOW)
|
E_DEC_OVERFLOW)
|
||||||
raise_integer_overflow();
|
raise_integer_overflow();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2005-2006 MySQL AB
|
/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -102,6 +102,24 @@ class my_decimal :public decimal_t
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
my_decimal(const my_decimal &rhs) : decimal_t(rhs)
|
||||||
|
{
|
||||||
|
for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
|
||||||
|
buffer[i]= rhs.buffer[i];
|
||||||
|
fix_buffer_pointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
my_decimal& operator=(const my_decimal &rhs)
|
||||||
|
{
|
||||||
|
if (this == &rhs)
|
||||||
|
return *this;
|
||||||
|
decimal_t::operator=(rhs);
|
||||||
|
for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
|
||||||
|
buffer[i]= rhs.buffer[i];
|
||||||
|
fix_buffer_pointer();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
len= DECIMAL_BUFF_LENGTH;
|
len= DECIMAL_BUFF_LENGTH;
|
||||||
@ -248,7 +266,6 @@ inline
|
|||||||
void my_decimal2decimal(const my_decimal *from, my_decimal *to)
|
void my_decimal2decimal(const my_decimal *from, my_decimal *to)
|
||||||
{
|
{
|
||||||
*to= *from;
|
*to= *from;
|
||||||
to->fix_buffer_pointer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2000-2006 MySQL AB
|
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -521,9 +521,6 @@ void field_decimal::add()
|
|||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
min_arg = max_arg = sum[0] = *dec;
|
min_arg = max_arg = sum[0] = *dec;
|
||||||
min_arg.fix_buffer_pointer();
|
|
||||||
max_arg.fix_buffer_pointer();
|
|
||||||
sum[0].fix_buffer_pointer();
|
|
||||||
my_decimal_mul(E_DEC_FATAL_ERROR, sum_sqr, dec, dec);
|
my_decimal_mul(E_DEC_FATAL_ERROR, sum_sqr, dec, dec);
|
||||||
cur_sum= 0;
|
cur_sum= 0;
|
||||||
min_length = max_length = length;
|
min_length = max_length = length;
|
||||||
@ -545,12 +542,10 @@ void field_decimal::add()
|
|||||||
if (my_decimal_cmp(dec, &min_arg) < 0)
|
if (my_decimal_cmp(dec, &min_arg) < 0)
|
||||||
{
|
{
|
||||||
min_arg= *dec;
|
min_arg= *dec;
|
||||||
min_arg.fix_buffer_pointer();
|
|
||||||
}
|
}
|
||||||
if (my_decimal_cmp(dec, &max_arg) > 0)
|
if (my_decimal_cmp(dec, &max_arg) > 0)
|
||||||
{
|
{
|
||||||
max_arg= *dec;
|
max_arg= *dec;
|
||||||
max_arg.fix_buffer_pointer();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2000 MySQL AB
|
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -13,8 +13,6 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
#line 18 "decimal.c"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=======================================================================
|
=======================================================================
|
||||||
NOTE: this library implements SQL standard "exact numeric" type
|
NOTE: this library implements SQL standard "exact numeric" type
|
||||||
|
Loading…
x
Reference in New Issue
Block a user