| Bug #5371 | Prepared query converting decimal to string blows the stack in 4.1.4 | ||
|---|---|---|---|
| Submitted: | 2 Sep 2004 16:12 | Modified: | 7 Sep 2004 12:24 |
| Reporter: | Nathaniel Blanchard | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server | Severity: | S1 (Critical) |
| Version: | 4.1.4-gamma | OS: | Any (All) |
| Assigned to: | Alexey Botchkov | CPU Architecture: | Any |
[3 Sep 2004 0:08]
Hartmut Holzgraefe
that should be either be limited to a total of 330 (+ '\0') or buff should be allocated dynamicly to be big enough ...
[3 Sep 2004 0:09]
Hartmut Holzgraefe
or, even better, use snprintf() ?
[7 Sep 2004 9:16]
Alexey Botchkov
bk commit - 4.1 tree (hf:1.1997) BUG#5371
[7 Sep 2004 12:24]
Alexey Botchkov
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.
If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information
about accessing the source trees is available at
http://www.mysql.com/doc/en/Installing_source_tree.html

Description: We use a generic access object that treats all fields as strings when querying the database. Thus, each field is given a buffer of size 999. As of 4.1.4, when retrieving a decimal field from the database, when it gets converted into a string, its blowing the stack due to a bad sprintf call. In libmysql.c: /* Resort to fetch_string_with_conversion: this should handle floating point -> string conversion nicely, honor all typecodes and param->offset possibly set in mysql_stmt_fetch_column */ char buff[331]; char *end; /* TODO: move this to a header shared between client and server. */ #define NOT_FIXED_DEC 31 if (field->decimals >= 31) #undef NOT_FIXED_DEC { sprintf(buff, "%-*.*g", (int) param->buffer_length, width, value); end= strcend(buff, ' '); *end= 0; } else { sprintf(buff, "%.*f", (int) field->decimals, value); end= strend(buff); } fetch_string_with_conversion(param, buff, (uint) (end - buff)); break; } } Note that buff is statically allocated to size 331, but the sprintf uses param->buffer_length, which in our case is 999. BOOM How to repeat: Use a prepared query against a field of type float, giving it a buffer of length > 331 and ask it to convert it into a string. Suggested fix: