From d0367abaffadaf43b7fb17750f5ec04eb2a5a97a Mon Sep 17 00:00:00 2001 From: Chaithra Gopalareddy Date: Wed, 22 May 2013 14:36:43 +0530 Subject: [PATCH] Bug#11766191:INVALID MEMORY READ IN DO_DIV_MOD WITH DOUBLY ASSIGNED VARIABLES Bug#12608543: CRASHES WITH DECIMALS AND STATEMENT NEEDS TO BE REPREPARED ERRORS Backporting these two fixes to 5.1 Added unittest to test my_decimal construtor and assignment operators --- configure.in | 2 +- sql/item_cmpfunc.cc | 1 - sql/my_decimal.h | 29 ++++++++++-- sql/sql_analyse.cc | 7 +-- strings/decimal.c | 5 +- unittest/Makefile.am | 6 +-- unittest/my_decimal/Makefile.am | 32 +++++++++++++ unittest/my_decimal/my_decimal-t.cc | 72 +++++++++++++++++++++++++++++ 8 files changed, 137 insertions(+), 17 deletions(-) create mode 100644 unittest/my_decimal/Makefile.am create mode 100644 unittest/my_decimal/my_decimal-t.cc diff --git a/configure.in b/configure.in index d9f69a8540d..3df96a547d2 100644 --- a/configure.in +++ b/configure.in @@ -2877,7 +2877,7 @@ fi AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl unittest/Makefile unittest/mytap/Makefile unittest/mytap/t/Makefile dnl unittest/mysys/Makefile unittest/strings/Makefile dnl - unittest/examples/Makefile dnl + unittest/examples/Makefile unittest/my_decimal/Makefile dnl strings/Makefile regex/Makefile storage/Makefile dnl man/Makefile BUILD/Makefile vio/Makefile dnl libmysql/Makefile libmysql_r/Makefile client/Makefile dnl diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3529a037940..db4fefbd249 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2077,7 +2077,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/my_decimal.h b/sql/my_decimal.h index 619976b9035..91df1b18dc0 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2013, 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 @@ -111,6 +111,31 @@ class my_decimal :public decimal_t #endif public: + my_decimal(const my_decimal &rhs) : decimal_t(rhs) + { +#if !defined(DBUG_OFF) + foo1= test_value; + foo2= test_value; +#endif + 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 !defined(DBUG_OFF) + foo1= test_value; + foo2= test_value; +#endif + 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() { @@ -147,8 +172,6 @@ public: void swap(my_decimal &rhs) { swap_variables(my_decimal, *this, rhs); - /* Swap the buffer pointers back */ - swap_variables(decimal_digit_t *, buf, rhs.buf); } }; diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 24169fddb97..13cf9beb029 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2013, 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 @@ -523,9 +523,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; @@ -547,12 +544,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(); } } } diff --git a/strings/decimal.c b/strings/decimal.c index 5cc3217a1c0..c2e1236c8ee 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2004, 2013, 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 @@ -14,8 +15,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#line 18 "decimal.c" - /* ======================================================================= NOTE: this library implements SQL standard "exact numeric" type diff --git a/unittest/Makefile.am b/unittest/Makefile.am index d6bc3be979b..f2d89449810 100644 --- a/unittest/Makefile.am +++ b/unittest/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, 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 @@ -13,12 +13,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SUBDIRS = mytap . mysys examples strings +SUBDIRS = mytap . mysys examples strings my_decimal EXTRA_DIST = unit.pl CLEANFILES = unit -unittests = mytap mysys strings @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@ +unittests = mytap mysys strings my_decimal @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@ test: perl unit.pl run $(unittests) diff --git a/unittest/my_decimal/Makefile.am b/unittest/my_decimal/Makefile.am new file mode 100644 index 00000000000..e40c2adb5b6 --- /dev/null +++ b/unittest/my_decimal/Makefile.am @@ -0,0 +1,32 @@ +# Copyright (c) 2013, 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 +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include +AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap +AM_CPPFLAGS += -I$(top_srcdir)/sql + +LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ + $(top_builddir)/mysys/libmysys.a \ + $(top_builddir)/strings/libmystrings.a \ + $(top_builddir)/dbug/libdbug.a \ + $(top_builddir)/mysys/libmysys.a \ + $(top_builddir)/strings/libmystrings.a + +my_decimal_t_SOURCES = my_decimal-t.cc + +noinst_PROGRAMS = my_decimal-t + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/unittest/my_decimal/my_decimal-t.cc b/unittest/my_decimal/my_decimal-t.cc new file mode 100644 index 00000000000..48d00465af9 --- /dev/null +++ b/unittest/my_decimal/my_decimal-t.cc @@ -0,0 +1,72 @@ +/* Copyright (c) 2013, 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "my_config.h" +#include "config.h" +#include +#include +#include +#include +#include +#include + + + +/* + Test my_decimal constuctor and assignement operators +*/ +static int +test_copy_and_compare() +{ + my_decimal d1,d2; + + ulonglong val= 42; + + ok(ulonglong2decimal(val,&d1) == 0, "Pass"); + d2= d1; + my_decimal d3(d1); + + ok(my_decimal_cmp(&d1, &d2) == 0, "Pass"); + ok(my_decimal_cmp(&d2, &d3) == 0, "Pass"); + ok(my_decimal_cmp(&d3, &d1) == 0,"Pass"); + + ulonglong val1, val2, val3; + ok(decimal2ulonglong(&d1, &val1) == 0, "Pass"); + ok(decimal2ulonglong(&d2, &val2) == 0,"Pass"); + ok(decimal2ulonglong(&d3, &val3) == 0,"Pass"); + + ok(val == val1,"Pass"); + ok(val == val2,"Pass"); + ok(val == val3,"Pass"); + + // The CTOR/operator=() generated by the compiler would fail here: + val= 45; + ok(ulonglong2decimal(val, &d1) == 0,"Pass"); + ok(my_decimal_cmp(&d1, &d2) == 1,"Pass"); + ok(my_decimal_cmp(&d1, &d3) == 1,"Pass"); + + return 0; + +} + +int main() +{ + plan(13); + diag("Testing my_decimal constructor and assignment operators"); + + test_copy_and_compare(); + + return exit_status(); +}