diff options
author | cmiller@zippy.cornsilk.net <> | 2007-08-31 15:24:43 -0400 |
---|---|---|
committer | cmiller@zippy.cornsilk.net <> | 2007-08-31 15:24:43 -0400 |
commit | 3185f0046d2b8363779f1e339d590c158f610daf (patch) | |
tree | a4312c3393e59c7c903a284b76a49c01dcd7bdc4 /sql/item_create.cc | |
parent | dc84a5fd5220459e41cf7cfaf53b9691aeabfbcf (diff) | |
download | mariadb-git-3185f0046d2b8363779f1e339d590c158f610daf.tar.gz |
Bug#15776: 32-bit signed int used for length of blob
Based on contributed patch from Martin Friebe, CLA from 2007-02-24.
The parser lacked support for field sizes after signed long,
when it should extend to 2**32-1.
Now, we correct that limitation, and also make the error handling
consistent for casts.
Diffstat (limited to 'sql/item_create.cc')
-rw-r--r-- | sql/item_create.cc | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/sql/item_create.cc b/sql/item_create.cc index 561613032bc..b7a9a1d7feb 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -464,8 +464,42 @@ Item *create_func_cast(Item *a, Cast_target cast_type, case ITEM_CAST_TIME: res= new Item_time_typecast(a); break; case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break; case ITEM_CAST_DECIMAL: - len= c_len ? atoi(c_len) : 0; - dec= c_dec ? atoi(c_dec) : 0; + if (c_len == NULL) + { + len= 0; + } + else + { + ulong decoded_size; + errno= 0; + decoded_size= strtoul(c_len, NULL, 10); + if (errno != 0) + { + my_error(ER_TOO_BIG_PRECISION, MYF(0), c_len, a->name, + DECIMAL_MAX_PRECISION); + return NULL; + } + len= decoded_size; + } + + if (c_dec == NULL) + { + dec= 0; + } + else + { + ulong decoded_size; + errno= 0; + decoded_size= strtoul(c_dec, NULL, 10); + if ((errno != 0) || (decoded_size > UINT_MAX)) + { + my_error(ER_TOO_BIG_SCALE, MYF(0), c_dec, a->name, + DECIMAL_MAX_SCALE); + return NULL; + } + dec= decoded_size; + } + my_decimal_trim(&len, &dec); if (len < dec) { @@ -486,8 +520,25 @@ Item *create_func_cast(Item *a, Cast_target cast_type, } res= new Item_decimal_typecast(a, len, dec); break; + case ITEM_CAST_CHAR: - len= c_len ? atoi(c_len) : -1; + if (c_len == NULL) + { + len= LL(-1); + } + else + { + ulong decoded_size; + errno= 0; + decoded_size= strtoul(c_len, NULL, 10); + if (errno != 0) + { + my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), "cast as char", MAX_FIELD_BLOBLENGTH); + return NULL; + } + len= decoded_size; + } + res= new Item_char_typecast(a, len, cs ? cs : current_thd->variables.collation_connection); break; |