diff options
author | unknown <peter@mysql.com> | 2002-10-30 19:39:52 +0300 |
---|---|---|
committer | unknown <peter@mysql.com> | 2002-10-30 19:39:52 +0300 |
commit | 6b5860130aed12a537f674d2a2ac867d24dc0528 (patch) | |
tree | 4a3246919ce49341c3f1b837b24fb6f9e5ff7fc3 | |
parent | 82d72d5e4440efa0270984e7aad16f80f4af3c5c (diff) | |
download | mariadb-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.cc | 35 |
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 */ |