From 995abb0ed20a19cf91615bf9ae5dca6c2ce44498 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Jul 2005 18:23:30 +0500 Subject: [PATCH] Fix for bug #10891 (string->decimal conversion crashes server) mysql-test/r/type_newdecimal.result: test result fixed mysql-test/t/type_newdecimal.test: test case added strings/decimal.c: new_point can be 0, and this case should be handled separately --- mysql-test/r/type_newdecimal.result | 3 +++ mysql-test/t/type_newdecimal.test | 5 +++++ strings/decimal.c | 19 ++++++++++++++----- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 79943df18c5..9ff4aea0567 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -934,3 +934,6 @@ select * from t1; col1 -9223372036854775808 drop table t1; +select cast('1.00000001335143196001808973960578441619873046875E-10' as decimal(30,15)); +cast('1.00000001335143196001808973960578441619873046875E-10' as decimal(30,15)) +0.000000000100000 diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index 5c4f288983b..41129870d6f 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -973,3 +973,8 @@ create table t1 (col1 bigint default -9223372036854775808); insert into t1 values (default); select * from t1; drop table t1; + +# +# Bug #10891 (converting to decimal crashes server) +# +select cast('1.00000001335143196001808973960578441619873046875E-10' as decimal(30,15)); diff --git a/strings/decimal.c b/strings/decimal.c index be403c5e3fb..76e62080ba0 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -739,11 +739,20 @@ int decimal_shift(decimal_t *dec, int shift) beg= ROUND_UP(beg + 1) - 1; end= ROUND_UP(end) - 1; DBUG_ASSERT(new_point >= 0); - new_point= ROUND_UP(new_point) - 1; - for(; new_point > end; new_point--) - dec->buf[new_point]= 0; - for(; new_point < beg; new_point++) - dec->buf[new_point]= 0; + + /* We don't want negative new_point below */ + if (new_point != 0) + new_point= ROUND_UP(new_point) - 1; + + if (new_point > end) + do + { + dec->buf[new_point]=0; + }while (--new_point > end); + else + for (; new_point < beg; new_point++) + dec->buf[new_point]= 0; + dec->intg= digits_int; dec->frac= digits_frac; return err;