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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
7c369a24
Commit
7c369a24
authored
Dec 18, 2004
by
konstantin@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More work on truncations in libmysql: after-review fixes.
parent
a2c9c8ea
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
54 additions
and
67 deletions
+54
-67
libmysql/libmysql.c
libmysql/libmysql.c
+52
-65
strings/my_strtoll10.c
strings/my_strtoll10.c
+1
-1
tests/client_test.c
tests/client_test.c
+1
-1
No files found.
libmysql/libmysql.c
View file @
7c369a24
...
@@ -3428,7 +3428,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
...
@@ -3428,7 +3428,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
{
{
char
*
buffer
=
(
char
*
)
param
->
buffer
;
char
*
buffer
=
(
char
*
)
param
->
buffer
;
int
err
=
0
;
int
err
=
0
;
char
*
endptr
;
char
*
endptr
=
value
+
length
;
/*
/*
This function should support all target buffer types: the rest
This function should support all target buffer types: the rest
...
@@ -3439,39 +3439,33 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
...
@@ -3439,39 +3439,33 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
break
;
break
;
case
MYSQL_TYPE_TINY
:
case
MYSQL_TYPE_TINY
:
{
{
longlong
data
=
my_strntoll
(
&
my_charset_latin1
,
value
,
length
,
10
,
longlong
data
=
my_strtoll10
(
value
,
&
endptr
,
&
err
);
&
endptr
,
&
err
);
*
param
->
error
=
(
IS_TRUNCATED
(
data
,
param
->
is_unsigned
,
*
param
->
error
=
(
IS_TRUNCATED
(
data
,
param
->
is_unsigned
,
INT_MIN8
,
INT_MAX8
,
UINT_MAX8
)
|
INT_MIN8
,
INT_MAX8
,
UINT_MAX8
)
||
err
>
0
);
test
(
err
));
*
buffer
=
(
uchar
)
data
;
*
buffer
=
(
uchar
)
data
;
break
;
break
;
}
}
case
MYSQL_TYPE_SHORT
:
case
MYSQL_TYPE_SHORT
:
{
{
longlong
data
=
my_strntoll
(
&
my_charset_latin1
,
value
,
length
,
10
,
longlong
data
=
my_strtoll10
(
value
,
&
endptr
,
&
err
);
&
endptr
,
&
err
);
*
param
->
error
=
(
IS_TRUNCATED
(
data
,
param
->
is_unsigned
,
*
param
->
error
=
(
IS_TRUNCATED
(
data
,
param
->
is_unsigned
,
INT_MIN16
,
INT_MAX16
,
UINT_MAX16
)
|
INT_MIN16
,
INT_MAX16
,
UINT_MAX16
)
||
err
>
0
);
test
(
err
));
shortstore
(
buffer
,
(
short
)
data
);
shortstore
(
buffer
,
(
short
)
data
);
break
;
break
;
}
}
case
MYSQL_TYPE_LONG
:
case
MYSQL_TYPE_LONG
:
{
{
longlong
data
=
my_strntoll
(
&
my_charset_latin1
,
value
,
length
,
10
,
longlong
data
=
my_strtoll10
(
value
,
&
endptr
,
&
err
);
&
endptr
,
&
err
);
*
param
->
error
=
(
IS_TRUNCATED
(
data
,
param
->
is_unsigned
,
*
param
->
error
=
(
IS_TRUNCATED
(
data
,
param
->
is_unsigned
,
INT_MIN32
,
INT_MAX32
,
UINT_MAX32
)
|
INT_MIN32
,
INT_MAX32
,
UINT_MAX32
)
||
err
>
0
);
test
(
err
));
longstore
(
buffer
,
(
int32
)
data
);
longstore
(
buffer
,
(
int32
)
data
);
break
;
break
;
}
}
case
MYSQL_TYPE_LONGLONG
:
case
MYSQL_TYPE_LONGLONG
:
{
{
longlong
data
=
my_str
ntoll
(
&
my_charset_latin1
,
value
,
length
,
10
,
longlong
data
=
my_str
toll10
(
value
,
&
endptr
,
&
err
);
&
endptr
,
&
err
);
*
param
->
error
=
param
->
is_unsigned
?
err
!=
0
:
*
param
->
error
=
test
(
err
);
(
err
>
0
||
(
err
==
0
&&
data
<
0
)
);
longlongstore
(
buffer
,
data
);
longlongstore
(
buffer
,
data
);
break
;
break
;
}
}
...
@@ -3554,10 +3548,9 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
...
@@ -3554,10 +3548,9 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
*/
*/
static
void
fetch_long_with_conversion
(
MYSQL_BIND
*
param
,
MYSQL_FIELD
*
field
,
static
void
fetch_long_with_conversion
(
MYSQL_BIND
*
param
,
MYSQL_FIELD
*
field
,
longlong
value
)
longlong
value
,
my_bool
is_unsigned
)
{
{
char
*
buffer
=
(
char
*
)
param
->
buffer
;
char
*
buffer
=
(
char
*
)
param
->
buffer
;
uint
field_is_unsigned
=
field
->
flags
&
UNSIGNED_FLAG
;
switch
(
param
->
buffer_type
)
{
switch
(
param
->
buffer_type
)
{
case
MYSQL_TYPE_NULL
:
/* do nothing */
case
MYSQL_TYPE_NULL
:
/* do nothing */
...
@@ -3579,38 +3572,38 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
...
@@ -3579,38 +3572,38 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
break
;
break
;
case
MYSQL_TYPE_LONGLONG
:
case
MYSQL_TYPE_LONGLONG
:
longlongstore
(
buffer
,
value
);
longlongstore
(
buffer
,
value
);
*
param
->
error
=
param
->
is_unsigned
!=
is_unsigned
&&
value
<
0
;
break
;
break
;
case
MYSQL_TYPE_FLOAT
:
case
MYSQL_TYPE_FLOAT
:
{
{
/*
We need to store data in the buffer before the truncation check to
workaround Intel FPU executive precision feature.
(See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 for details)
AFAIU it does not guarantee to work.
*/
float
data
;
float
data
;
if
(
field_is_unsigned
)
if
(
is_unsigned
)
{
data
=
(
float
)
ulonglong2double
(
value
);
data
=
(
float
)
ulonglong2double
(
value
);
*
param
->
error
=
(
ulonglong
)
data
!=
(
ulonglong
)
value
;
}
else
else
{
data
=
(
float
)
value
;
data
=
(
float
)
value
;
/* printf("%lld, %f\n", value, data); */
*
param
->
error
=
value
!=
((
longlong
)
data
);
}
floatstore
(
buffer
,
data
);
floatstore
(
buffer
,
data
);
*
param
->
error
=
is_unsigned
?
((
ulonglong
)
value
)
!=
((
ulonglong
)
(
*
(
float
*
)
buffer
))
:
((
longlong
)
value
)
!=
((
longlong
)
(
*
(
float
*
)
buffer
));
break
;
break
;
}
}
case
MYSQL_TYPE_DOUBLE
:
case
MYSQL_TYPE_DOUBLE
:
{
{
double
data
;
double
data
;
if
(
field_is_unsigned
)
if
(
is_unsigned
)
{
data
=
ulonglong2double
(
value
);
data
=
ulonglong2double
(
value
);
*
param
->
error
=
(
ulonglong
)
data
!=
(
ulonglong
)
value
;
}
else
else
{
data
=
value
;
data
=
value
;
*
param
->
error
=
(
longlong
)
data
!=
value
;
}
doublestore
(
buffer
,
data
);
doublestore
(
buffer
,
data
);
*
param
->
error
=
is_unsigned
?
((
ulonglong
)
value
)
!=
((
ulonglong
)
(
*
(
double
*
)
buffer
))
:
((
longlong
)
value
)
!=
((
longlong
)
(
*
(
double
*
)
buffer
));
break
;
break
;
}
}
case
MYSQL_TYPE_TIME
:
case
MYSQL_TYPE_TIME
:
...
@@ -3626,7 +3619,7 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
...
@@ -3626,7 +3619,7 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
default:
default:
{
{
char
buff
[
22
];
/* Enough for longlong */
char
buff
[
22
];
/* Enough for longlong */
char
*
end
=
longlong10_to_str
(
value
,
buff
,
field_
is_unsigned
?
10
:
-
10
);
char
*
end
=
longlong10_to_str
(
value
,
buff
,
is_unsigned
?
10
:
-
10
);
/* Resort to string conversion which supports all typecodes */
/* Resort to string conversion which supports all typecodes */
uint
length
=
(
uint
)
(
end
-
buff
);
uint
length
=
(
uint
)
(
end
-
buff
);
...
@@ -3665,74 +3658,67 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
...
@@ -3665,74 +3658,67 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
case
MYSQL_TYPE_NULL
:
/* do nothing */
case
MYSQL_TYPE_NULL
:
/* do nothing */
break
;
break
;
case
MYSQL_TYPE_TINY
:
case
MYSQL_TYPE_TINY
:
{
/*
We need to _store_ data in the buffer before the truncation check to
workaround Intel FPU executive precision feature.
(See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 for details)
Sic: AFAIU it does not guarantee to work.
*/
if
(
param
->
is_unsigned
)
if
(
param
->
is_unsigned
)
{
*
buffer
=
(
uint8
)
value
;
int8
data
=
(
int8
)
value
;
*
param
->
error
=
(
double
)
data
!=
value
;
*
buffer
=
(
uchar
)
data
;
}
else
else
{
*
buffer
=
(
int8
)
value
;
uchar
data
=
(
uchar
)
value
;
*
param
->
error
=
value
!=
(
param
->
is_unsigned
?
(
double
)
((
uint8
)
*
buffer
)
:
*
param
->
error
=
(
double
)
data
!=
value
;
(
double
)
((
int8
)
*
buffer
));
*
buffer
=
data
;
}
break
;
break
;
}
case
MYSQL_TYPE_SHORT
:
case
MYSQL_TYPE_SHORT
:
{
if
(
param
->
is_unsigned
)
if
(
param
->
is_unsigned
)
{
{
ushort
data
=
(
ushort
)
value
;
ushort
data
=
(
ushort
)
value
;
*
param
->
error
=
(
double
)
data
!=
value
;
shortstore
(
buffer
,
data
);
shortstore
(
buffer
,
data
);
}
}
else
else
{
{
short
data
=
(
short
)
value
;
short
data
=
(
short
)
value
;
*
param
->
error
=
(
double
)
data
!=
value
;
shortstore
(
buffer
,
data
);
shortstore
(
buffer
,
data
);
}
}
*
param
->
error
=
value
!=
(
param
->
is_unsigned
?
(
double
)
(
*
(
ushort
*
)
buffer
)
:
(
double
)
(
*
(
short
*
)
buffer
));
break
;
break
;
}
case
MYSQL_TYPE_LONG
:
case
MYSQL_TYPE_LONG
:
{
if
(
param
->
is_unsigned
)
if
(
param
->
is_unsigned
)
{
{
uint32
data
=
(
uint32
)
value
;
uint32
data
=
(
uint32
)
value
;
*
param
->
error
=
(
double
)
data
!=
value
;
longstore
(
buffer
,
data
);
longstore
(
buffer
,
data
);
}
}
else
else
{
{
int32
data
=
(
int32
)
value
;
int32
data
=
(
int32
)
value
;
*
param
->
error
=
(
double
)
data
!=
value
;
longstore
(
buffer
,
data
);
longstore
(
buffer
,
data
);
}
}
*
param
->
error
=
value
!=
(
param
->
is_unsigned
?
(
double
)
(
*
(
uint32
*
)
buffer
)
:
(
double
)
(
*
(
int32
*
)
buffer
));
break
;
break
;
}
case
MYSQL_TYPE_LONGLONG
:
case
MYSQL_TYPE_LONGLONG
:
{
if
(
param
->
is_unsigned
)
if
(
param
->
is_unsigned
)
{
{
ulonglong
data
=
(
ulonglong
)
value
;
ulonglong
data
=
(
ulonglong
)
value
;
*
param
->
error
=
(
double
)
data
!=
value
;
longlongstore
(
buffer
,
data
);
longlongstore
(
buffer
,
data
);
}
}
else
else
{
{
longlong
data
=
(
longlong
)
value
;
longlong
data
=
(
longlong
)
value
;
*
param
->
error
=
(
double
)
data
!=
value
;
longlongstore
(
buffer
,
data
);
longlongstore
(
buffer
,
data
);
}
}
*
param
->
error
=
value
!=
(
param
->
is_unsigned
?
(
double
)
(
*
(
ulonglong
*
)
buffer
)
:
(
double
)
(
*
(
longlong
*
)
buffer
));
break
;
break
;
}
case
MYSQL_TYPE_FLOAT
:
case
MYSQL_TYPE_FLOAT
:
{
{
float
data
=
(
float
)
value
;
float
data
=
(
float
)
value
;
*
param
->
error
=
data
!=
value
;
floatstore
(
buffer
,
data
);
floatstore
(
buffer
,
data
);
*
param
->
error
=
(
*
(
float
*
)
buffer
)
!=
value
;
break
;
break
;
}
}
case
MYSQL_TYPE_DOUBLE
:
case
MYSQL_TYPE_DOUBLE
:
...
@@ -3824,7 +3810,7 @@ static void fetch_datetime_with_conversion(MYSQL_BIND *param,
...
@@ -3824,7 +3810,7 @@ static void fetch_datetime_with_conversion(MYSQL_BIND *param,
case
MYSQL_TYPE_LONGLONG
:
case
MYSQL_TYPE_LONGLONG
:
{
{
longlong
value
=
(
longlong
)
TIME_to_ulonglong
(
time
);
longlong
value
=
(
longlong
)
TIME_to_ulonglong
(
time
);
fetch_long_with_conversion
(
param
,
field
,
value
);
fetch_long_with_conversion
(
param
,
field
,
value
,
TRUE
);
break
;
break
;
}
}
default:
default:
...
@@ -3872,7 +3858,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
...
@@ -3872,7 +3858,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
/* sic: we need to cast to 'signed char' as 'char' may be unsigned */
/* sic: we need to cast to 'signed char' as 'char' may be unsigned */
longlong
data
=
field_is_unsigned
?
(
longlong
)
value
:
longlong
data
=
field_is_unsigned
?
(
longlong
)
value
:
(
longlong
)
(
signed
char
)
value
;
(
longlong
)
(
signed
char
)
value
;
fetch_long_with_conversion
(
param
,
field
,
data
);
fetch_long_with_conversion
(
param
,
field
,
data
,
0
);
*
row
+=
1
;
*
row
+=
1
;
break
;
break
;
}
}
...
@@ -3882,7 +3868,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
...
@@ -3882,7 +3868,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
short
value
=
sint2korr
(
*
row
);
short
value
=
sint2korr
(
*
row
);
longlong
data
=
field_is_unsigned
?
(
longlong
)
(
unsigned
short
)
value
:
longlong
data
=
field_is_unsigned
?
(
longlong
)
(
unsigned
short
)
value
:
(
longlong
)
value
;
(
longlong
)
value
;
fetch_long_with_conversion
(
param
,
field
,
data
);
fetch_long_with_conversion
(
param
,
field
,
data
,
0
);
*
row
+=
2
;
*
row
+=
2
;
break
;
break
;
}
}
...
@@ -3892,14 +3878,15 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
...
@@ -3892,14 +3878,15 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
long
value
=
sint4korr
(
*
row
);
long
value
=
sint4korr
(
*
row
);
longlong
data
=
field_is_unsigned
?
(
longlong
)
(
unsigned
long
)
value
:
longlong
data
=
field_is_unsigned
?
(
longlong
)
(
unsigned
long
)
value
:
(
longlong
)
value
;
(
longlong
)
value
;
fetch_long_with_conversion
(
param
,
field
,
data
);
fetch_long_with_conversion
(
param
,
field
,
data
,
0
);
*
row
+=
4
;
*
row
+=
4
;
break
;
break
;
}
}
case
MYSQL_TYPE_LONGLONG
:
case
MYSQL_TYPE_LONGLONG
:
{
{
longlong
value
=
(
longlong
)
sint8korr
(
*
row
);
longlong
value
=
(
longlong
)
sint8korr
(
*
row
);
fetch_long_with_conversion
(
param
,
field
,
value
);
fetch_long_with_conversion
(
param
,
field
,
value
,
field
->
flags
&
UNSIGNED_FLAG
);
*
row
+=
8
;
*
row
+=
8
;
break
;
break
;
}
}
...
...
strings/my_strtoll10.c
View file @
7c369a24
...
@@ -46,7 +46,7 @@ static unsigned long lfactor[9]=
...
@@ -46,7 +46,7 @@ static unsigned long lfactor[9]=
from string nptr and converts it to an signed or unsigned
from string nptr and converts it to an signed or unsigned
long long integer value.
long long integer value.
Space characters and tab are ignored.
Space characters and tab are ignored.
A sign character might precede the
the
digit characters. The number
A sign character might precede the digit characters. The number
may have any number of pre-zero digits.
may have any number of pre-zero digits.
The function stops reading the string nptr at the first character
The function stops reading the string nptr at the first character
...
...
tests/client_test.c
View file @
7c369a24
...
@@ -12240,7 +12240,7 @@ static void test_truncation()
...
@@ -12240,7 +12240,7 @@ static void test_truncation()
/* int -> float: truncation, not enough bits in float */
/* int -> float: truncation, not enough bits in float */
DIE_UNLESS
(
++
bind
<
bind_array
+
bind_count
);
DIE_UNLESS
(
++
bind
<
bind_array
+
bind_count
);
/* do nothing: due to a gcc bug result here is not predictable */
DIE_UNLESS
(
*
bind
->
error
);
/* int -> double: no truncation */
/* int -> double: no truncation */
DIE_UNLESS
(
++
bind
<
bind_array
+
bind_count
);
DIE_UNLESS
(
++
bind
<
bind_array
+
bind_count
);
...
...
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