Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
043ea441
Commit
043ea441
authored
Oct 30, 2002
by
peter@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Decimal field fix overflow
parent
bac793e2
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
16 additions
and
19 deletions
+16
-19
sql/field.cc
sql/field.cc
+16
-19
No files found.
sql/field.cc
View file @
043ea441
...
@@ -41,6 +41,11 @@
...
@@ -41,6 +41,11 @@
#include <floatingpoint.h>
#include <floatingpoint.h>
#endif
#endif
// Maximum allowed exponent value for converting string to decimal
#define MAX_EXPONENT 1024
/*****************************************************************************
/*****************************************************************************
Instansiate templates and static variables
Instansiate templates and static variables
*****************************************************************************/
*****************************************************************************/
...
@@ -367,7 +372,6 @@ void Field_decimal::store(const char *from,uint len)
...
@@ -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") */
/* The pointer where the field value starts (i.e., "where to write") */
char
*
to
=
ptr
;
char
*
to
=
ptr
;
uint
tmp_dec
,
tmp_uint
;
uint
tmp_dec
,
tmp_uint
;
ulonglong
tmp_ulonglong
;
/*
/*
The sign of the number : will be 0 (means positive but sign not
The sign of the number : will be 0 (means positive but sign not
specified), '+' or '-'
specified), '+' or '-'
...
@@ -381,8 +385,7 @@ void Field_decimal::store(const char *from,uint len)
...
@@ -381,8 +385,7 @@ void Field_decimal::store(const char *from,uint len)
const
char
*
frac_digits_from
,
*
frac_digits_end
;
const
char
*
frac_digits_from
,
*
frac_digits_end
;
/* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */
/* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */
char
expo_sign_char
=
0
;
char
expo_sign_char
=
0
;
uint
exponent
=
0
;
// value of the exponent
uint
exponent
=
0
;
// value of the exponent
ulonglong
exponent_ulonglong
=
0
;
/*
/*
Pointers used when digits move from the left of the '.' to the
Pointers used when digits move from the left of the '.' to the
right of the '.' (explained below)
right of the '.' (explained below)
...
@@ -485,14 +488,13 @@ void Field_decimal::store(const char *from,uint len)
...
@@ -485,14 +488,13 @@ void Field_decimal::store(const char *from,uint len)
*/
*/
for
(;
from
!=
end
&&
isdigit
(
*
from
);
from
++
)
for
(;
from
!=
end
&&
isdigit
(
*
from
);
from
++
)
{
{
exponent
_ulonglong
=
10
*
exponent_ulonglong
+
(
ulonglong
)
(
*
from
-
'0'
);
exponent
=
10
*
exponent
+
(
*
from
-
'0'
);
if
(
exponent
_ulonglong
>
(
ulonglong
)
UINT_MAX
)
if
(
exponent
>
MAX_EXPONENT
)
{
{
exponent
_ulonglong
=
(
ulonglong
)
UINT_MAX
;
exponent
=
MAX_EXPONENT
;
break
;
break
;
}
}
}
}
exponent
=
(
uint
)(
exponent_ulonglong
);
}
}
/*
/*
...
@@ -534,21 +536,21 @@ void Field_decimal::store(const char *from,uint len)
...
@@ -534,21 +536,21 @@ void Field_decimal::store(const char *from,uint len)
*/
*/
/*
/*
Below tmp_u
longulong cannot overflow
,
Below tmp_u
int cannot overflow with small enough MAX_EXPONENT setting
,
as int_digits_added_zeros<=exponent<4G and
as int_digits_added_zeros<=exponent<4G and
(ulonglong)(int_digits_end-int_digits_from)<=max_allowed_packet<=2G 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
(ulonglong)(frac_digits_from-int_digits_tail_from)<=max_allowed_packet<=2G
*/
*/
if
(
!
expo_sign_char
)
if
(
!
expo_sign_char
)
tmp_u
longlong
=
(
ulonglong
)
tmp_dec
+
(
ulonglong
)(
int_digits_end
-
int_digits_from
);
tmp_u
int
=
tmp_dec
+
(
uint
)(
int_digits_end
-
int_digits_from
);
else
if
(
expo_sign_char
==
'-'
)
else
if
(
expo_sign_char
==
'-'
)
{
{
tmp_uint
=
min
(
exponent
,(
uint
)(
int_digits_end
-
int_digits_from
));
tmp_uint
=
min
(
exponent
,(
uint
)(
int_digits_end
-
int_digits_from
));
frac_digits_added_zeros
=
exponent
-
tmp_uint
;
frac_digits_added_zeros
=
exponent
-
tmp_uint
;
int_digits_end
-=
tmp_uint
;
int_digits_end
-=
tmp_uint
;
frac_digits_head_end
=
int_digits_end
+
tmp_uint
;
frac_digits_head_end
=
int_digits_end
+
tmp_uint
;
tmp_u
longlong
=
(
ulonglong
)
tmp_dec
+
(
ulonglong
)(
int_digits_end
-
int_digits_from
);
tmp_u
int
=
tmp_dec
+
(
uint
)(
int_digits_end
-
int_digits_from
);
}
}
else
// (expo_sign_char=='+')
else
// (expo_sign_char=='+')
{
{
...
@@ -575,9 +577,9 @@ void Field_decimal::store(const char *from,uint len)
...
@@ -575,9 +577,9 @@ void Field_decimal::store(const char *from,uint len)
int_digits_added_zeros
=
0
;
int_digits_added_zeros
=
0
;
}
}
}
}
tmp_u
longlong
=
(
ulonglong
)
tmp_dec
+
(
ulonglong
)
(
int_digits_end
-
int_digits_from
)
tmp_u
int
=
tmp_dec
+
(
int_digits_end
-
int_digits_from
)
+
(
u
longlong
)(
frac_digits_from
-
int_digits_tail_from
)
+
+
(
u
int
)(
frac_digits_from
-
int_digits_tail_from
)
+
(
ulonglong
)
int_digits_added_zeros
;
int_digits_added_zeros
;
}
}
/*
/*
...
@@ -588,7 +590,7 @@ void Field_decimal::store(const char *from,uint len)
...
@@ -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 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
//the rightmost sum above cannot overflow
{
{
// too big number, change to max or min number
// too big number, change to max or min number
...
@@ -596,11 +598,6 @@ void Field_decimal::store(const char *from,uint len)
...
@@ -596,11 +598,6 @@ void Field_decimal::store(const char *from,uint len)
return
;
return
;
}
}
/*
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
Tmp_left_pos is the position where the leftmost digit of
the int_% parts will be written
the int_% parts will be written
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment