summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorTor Didriksen <tor.didriksen@oracle.com>2011-01-14 10:05:14 +0100
committerTor Didriksen <tor.didriksen@oracle.com>2011-01-14 10:05:14 +0100
commit7bf234032a6debc28f24fbbffe7e3cacb7b1803b (patch)
treea6039675e5fcc73cb3cde80664b6c2e4f1f83294 /sql
parentff2b529918c2c12d4a29f8f34c5d9afbf5e40464 (diff)
downloadmariadb-git-7bf234032a6debc28f24fbbffe7e3cacb7b1803b.tar.gz
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.
Diffstat (limited to 'sql')
-rw-r--r--sql/item_cmpfunc.cc3
-rw-r--r--sql/item_func.cc16
-rw-r--r--sql/my_decimal.h21
-rw-r--r--sql/sql_analyse.cc7
4 files changed, 28 insertions, 19 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ac13ca8a8c5..5e9c0fc78b8 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -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
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)
{
range->dec= *dec;
- range->dec.fix_buffer_pointer();
}
}
else
diff --git a/sql/item_func.cc b/sql/item_func.cc
index d959e59337d..47007d8a71c 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -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
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 ||
args[1]->result_type() != INT_RESULT)
{
- my_decimal value0, value1, tmp;
- my_decimal *val0, *val1;
- longlong res;
- int err;
-
- val0= args[0]->val_decimal(&value0);
- val1= args[1]->val_decimal(&value1);
+ my_decimal tmp;
+ my_decimal val0= *args[0]->val_decimal(&tmp);
+ my_decimal val1= *args[1]->val_decimal(&tmp);
if ((null_value= (args[0]->null_value || args[1]->null_value)))
return 0;
+ int err;
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)
signal_divide_by_null();
return 0;
}
+ longlong res;
if (my_decimal2int(E_DEC_FATAL_ERROR, &tmp, unsigned_flag, &res) &
E_DEC_OVERFLOW)
raise_integer_overflow();
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index e5b1573608a..e2f5c95dac2 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -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
it under the terms of the GNU General Public License as published by
@@ -102,6 +102,24 @@ class my_decimal :public decimal_t
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()
{
len= DECIMAL_BUFF_LENGTH;
@@ -248,7 +266,6 @@ inline
void my_decimal2decimal(const my_decimal *from, my_decimal *to)
{
*to= *from;
- to->fix_buffer_pointer();
}
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 4b6756188dd..e3c0ed28052 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -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
it under the terms of the GNU General Public License as published by
@@ -521,9 +521,6 @@ void field_decimal::add()
{
found = 1;
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);
cur_sum= 0;
min_length = max_length = length;
@@ -545,12 +542,10 @@ void field_decimal::add()
if (my_decimal_cmp(dec, &min_arg) < 0)
{
min_arg= *dec;
- min_arg.fix_buffer_pointer();
}
if (my_decimal_cmp(dec, &max_arg) > 0)
{
max_arg= *dec;
- max_arg.fix_buffer_pointer();
}
}
}