summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <peter@mysql.com>2002-10-30 19:39:52 +0300
committerunknown <peter@mysql.com>2002-10-30 19:39:52 +0300
commit6b5860130aed12a537f674d2a2ac867d24dc0528 (patch)
tree4a3246919ce49341c3f1b837b24fb6f9e5ff7fc3
parent82d72d5e4440efa0270984e7aad16f80f4af3c5c (diff)
downloadmariadb-git-6b5860130aed12a537f674d2a2ac867d24dc0528.tar.gz
Decimal field fix overflow
sql/field.cc: Fixes for Decimal crash bug patch according to Monty's comments ?
-rw-r--r--sql/field.cc35
1 files changed, 16 insertions, 19 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 9cb13e96cc1..f06cd7b3604 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -41,6 +41,11 @@
#include <floatingpoint.h>
#endif
+// Maximum allowed exponent value for converting string to decimal
+#define MAX_EXPONENT 1024
+
+
+
/*****************************************************************************
Instansiate templates and static variables
*****************************************************************************/
@@ -367,7 +372,6 @@ void Field_decimal::store(const char *from,uint len)
/* The pointer where the field value starts (i.e., "where to write") */
char *to=ptr;
uint tmp_dec, tmp_uint;
- ulonglong tmp_ulonglong;
/*
The sign of the number : will be 0 (means positive but sign not
specified), '+' or '-'
@@ -381,8 +385,7 @@ void Field_decimal::store(const char *from,uint len)
const char *frac_digits_from, *frac_digits_end;
/* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */
char expo_sign_char=0;
- uint exponent=0; // value of the exponent
- ulonglong exponent_ulonglong=0;
+ uint exponent=0; // value of the exponent
/*
Pointers used when digits move from the left of the '.' to the
right of the '.' (explained below)
@@ -485,14 +488,13 @@ void Field_decimal::store(const char *from,uint len)
*/
for (;from!=end && isdigit(*from); from++)
{
- exponent_ulonglong=10*exponent_ulonglong+(ulonglong)(*from-'0');
- if (exponent_ulonglong>(ulonglong)UINT_MAX)
+ exponent=10*exponent+(*from-'0');
+ if (exponent>MAX_EXPONENT)
{
- exponent_ulonglong=(ulonglong)UINT_MAX;
+ exponent=MAX_EXPONENT;
break;
}
}
- exponent=(uint)(exponent_ulonglong);
}
/*
@@ -534,21 +536,21 @@ void Field_decimal::store(const char *from,uint len)
*/
/*
- Below tmp_ulongulong cannot overflow,
+ Below tmp_uint cannot overflow with small enough MAX_EXPONENT setting,
as int_digits_added_zeros<=exponent<4G and
(ulonglong)(int_digits_end-int_digits_from)<=max_allowed_packet<=2G and
(ulonglong)(frac_digits_from-int_digits_tail_from)<=max_allowed_packet<=2G
*/
if (!expo_sign_char)
- tmp_ulonglong=(ulonglong)tmp_dec+(ulonglong)(int_digits_end-int_digits_from);
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
else if (expo_sign_char == '-')
{
tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
frac_digits_added_zeros=exponent-tmp_uint;
int_digits_end -= tmp_uint;
frac_digits_head_end=int_digits_end+tmp_uint;
- tmp_ulonglong=(ulonglong)tmp_dec+(ulonglong)(int_digits_end-int_digits_from);
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
}
else // (expo_sign_char=='+')
{
@@ -575,9 +577,9 @@ void Field_decimal::store(const char *from,uint len)
int_digits_added_zeros=0;
}
}
- tmp_ulonglong=(ulonglong)tmp_dec+(ulonglong)(int_digits_end-int_digits_from)
- +(ulonglong)(frac_digits_from-int_digits_tail_from)+
- (ulonglong)int_digits_added_zeros;
+ tmp_uint=tmp_dec+(int_digits_end-int_digits_from)
+ +(uint)(frac_digits_from-int_digits_tail_from)+
+ int_digits_added_zeros;
}
/*
@@ -588,7 +590,7 @@ void Field_decimal::store(const char *from,uint len)
If the sign is defined and '-', we need one position for it
*/
- if ((ulonglong)field_length < tmp_ulonglong + (ulonglong) (sign_char == '-'))
+ if (field_length < tmp_uint + (sign_char == '-'))
//the rightmost sum above cannot overflow
{
// too big number, change to max or min number
@@ -597,11 +599,6 @@ void Field_decimal::store(const char *from,uint len)
}
/*
- If the above test was ok, then tmp_ulonglong<4G and the following cast is valid
- */
- tmp_uint=(uint)tmp_ulonglong;
-
- /*
Tmp_left_pos is the position where the leftmost digit of
the int_% parts will be written
*/