summaryrefslogtreecommitdiff
path: root/strings/ctype-ucs2.c
diff options
context:
space:
mode:
authorunknown <knielsen@loke.(none)>2007-10-31 10:34:26 +0100
committerunknown <knielsen@loke.(none)>2007-10-31 10:34:26 +0100
commit0b023e98911bcc947f0e57fd15b549be7415ed9f (patch)
tree8d9c36f9a96e41cc8635d043cb5bea05bb7f5739 /strings/ctype-ucs2.c
parent6c9993f7203f13f5d8be04c5df63697bce19e7d4 (diff)
downloadmariadb-git-0b023e98911bcc947f0e57fd15b549be7415ed9f.tar.gz
BUG#31799: Scrambled number output due to integer overflow
An integer overflow in number->string conversion caused completely wrong output of the number LONGLONG_MIN with gcc 4.2.1. Fixed by eliminating the overflow, using only operations that are well-defined in ANSI C. strings/ctype-simple.c: An integer overflow in number->string conversion caused completely wrong output of the number LONGLONG_MIN with gcc 4.2.1. Fixed by eliminating the overflow, using only operations that are well-defined in ANSI C. strings/ctype-ucs2.c: An integer overflow in number->string conversion caused completely wrong output of the number LONGLONG_MIN with gcc 4.2.1. Fixed by eliminating the overflow, using only operations that are well-defined in ANSI C. strings/int2str.c: An integer overflow in number->string conversion caused completely wrong output of the number LONGLONG_MIN with gcc 4.2.1. Fixed by eliminating the overflow, using only operations that are well-defined in ANSI C. strings/longlong2str.c: An integer overflow in number->string conversion caused completely wrong output of the number LONGLONG_MIN with gcc 4.2.1. Fixed by eliminating the overflow, using only operations that are well-defined in ANSI C.
Diffstat (limited to 'strings/ctype-ucs2.c')
-rw-r--r--strings/ctype-ucs2.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index b5353c55e4c..97e5defdec1 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -1018,6 +1018,7 @@ int my_l10tostr_ucs2(CHARSET_INFO *cs,
register char *p, *db, *de;
long int new_val;
int sl=0;
+ unsigned long int uval = (unsigned long int) val;
p = &buffer[sizeof(buffer)-1];
*p='\0';
@@ -1027,12 +1028,13 @@ int my_l10tostr_ucs2(CHARSET_INFO *cs,
if (val < 0)
{
sl = 1;
- val = -val;
+ /* Avoid integer overflow in (-val) for LONGLONG_MIN (BUG#31799). */
+ uval = (unsigned long int)0 - uval;
}
}
- new_val = (long) ((unsigned long int) val / 10);
- *--p = '0'+ (char) ((unsigned long int) val - (unsigned long) new_val * 10);
+ new_val = (long) (uval / 10);
+ *--p = '0'+ (char) (uval - (unsigned long) new_val * 10);
val = new_val;
while (val != 0)
@@ -1065,34 +1067,36 @@ int my_ll10tostr_ucs2(CHARSET_INFO *cs __attribute__((unused)),
register char *p, *db, *de;
long long_val;
int sl=0;
+ ulonglong uval= (ulonglong) val;
if (radix < 0)
{
if (val < 0)
{
sl=1;
- val = -val;
+ /* Avoid integer overflow in (-val) for LONGLONG_MIN (BUG#31799). */
+ uval = (ulonglong)0 - uval;
}
}
p = &buffer[sizeof(buffer)-1];
*p='\0';
- if (val == 0)
+ if (uval == 0)
{
*--p='0';
goto cnv;
}
- while ((ulonglong) val > (ulonglong) LONG_MAX)
+ while (uval > (ulonglong) LONG_MAX)
{
- ulonglong quo=(ulonglong) val/(uint) 10;
- uint rem= (uint) (val- quo* (uint) 10);
+ ulonglong quo= uval/(uint) 10;
+ uint rem= (uint) (uval- quo* (uint) 10);
*--p = '0' + rem;
- val= quo;
+ uval= quo;
}
- long_val= (long) val;
+ long_val= (long) uval;
while (long_val != 0)
{
long quo= long_val/10;