diff options
author | Alexander Barkov <bar@mysql.com> | 2010-11-19 18:24:29 +0300 |
---|---|---|
committer | Alexander Barkov <bar@mysql.com> | 2010-11-19 18:24:29 +0300 |
commit | 677639f46adb7cfcb7147d11aed87aab1ca18c27 (patch) | |
tree | efbe34819c43d94c8b3ea1f93af2d718e0dbb796 /sql | |
parent | 1ab1cb8a77780f9dd4c70d8d93be0b92925533a5 (diff) | |
download | mariadb-git-677639f46adb7cfcb7147d11aed87aab1ca18c27.tar.gz |
Bug#58175 xml functions read initialized bytes when conversions happen
Problem:
nr_of_decimals could read behind the end of the buffer
in case of a non-null-terminated string, which caused
valgring warnings.
Fix:
fixing nr_of_decimals not to read behind the "end" pointer.
modified:
@ mysql-test/r/xml.result
@ mysql-test/t/xml.test
@ sql/item.cc
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/sql/item.cc b/sql/item.cc index 5433693b513..e14c3c95934 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5527,10 +5527,27 @@ static uint nr_of_decimals(const char *str, const char *end) break; } decimal_point= str; - for (; my_isdigit(system_charset_info, *str) ; str++) + for ( ; str < end && my_isdigit(system_charset_info, *str) ; str++) ; - if (*str == 'e' || *str == 'E') + if (str < end && (*str == 'e' || *str == 'E')) return NOT_FIXED_DEC; + /* + QQ: + The number of decimal digist in fact should be (str - decimal_point - 1). + But it seems the result of nr_of_decimals() is never used! + + In case of 'e' and 'E' nr_of_decimals returns NOT_FIXED_DEC. + In case if there is no 'e' or 'E' parser code in sql_yacc.yy + never calls Item_float::Item_float() - it creates Item_decimal instead. + + The only piece of code where we call Item_float::Item_float(str, len) + without having 'e' or 'E' is item_xmlfunc.cc, but this Item_float + never appears in metadata itself. Changing the code to return + (str - decimal_point - 1) does not make any changes in the test results. + + This should be addressed somehow. + Looks like a reminder from before real DECIMAL times. + */ return (uint) (str - decimal_point); } |