summaryrefslogtreecommitdiff
path: root/sql/item_create.cc
diff options
context:
space:
mode:
authorunknown <cmiller@zippy.cornsilk.net>2008-04-01 12:19:20 -0400
committerunknown <cmiller@zippy.cornsilk.net>2008-04-01 12:19:20 -0400
commit9efddcf6e2facc7ed21e755785c3cec9f76f71b2 (patch)
tree5183d59a343bde1ac1ada477245436ea92e30b26 /sql/item_create.cc
parent33529392d38f2653c7596a2d8714478c8d908f55 (diff)
downloadmariadb-git-9efddcf6e2facc7ed21e755785c3cec9f76f71b2.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. --- Fix minor complaints of Marc Alff, for patch against B-g#15776. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/bug15776/my50-bug15776 into zippy.cornsilk.net:/home/cmiller/work/mysql/bug15776/my51-bug15776 --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/bug15776/my51-bug15776 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.1-build --- testing mysql-test/r/type_blob.result: Verify that blobs may be created with the size that is already documented. Additionally, test the limits of several other types. mysql-test/t/type_blob.test: Verify that blobs may be created with the size that is already documented. Additionally, test the limits of several other types. --- Drop table in case we start from a bad state. sql/field.cc: atoi() insufficient to gauge the length of some fields. Change it to strtoul(). sql/item_create.cc: atoi() insufficient to gauge the length of some fields. Change it to strtoul(). If a casted length is too long, raise an error. sql/share/errmsg.txt: Change ER_TOO_BIG_FIELDLENGTH so that it can accept sizes larger than 2**15 -- instead, 2**32. --- Manual merge. sql/sql_yacc.yy: Make lengths take, in addition to NUM, LONG_NUM, ULONGLONG_NUM, and DECIMAL_NUM. --- yacc/bison is left-recursive, so FIXME statement is wrong. --- Manual merge and reformatting. sql/unireg.h: Define new constant.
Diffstat (limited to 'sql/item_create.cc')
-rw-r--r--sql/item_create.cc54
1 files changed, 51 insertions, 3 deletions
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 49cc33b95a7..427857c58ad 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -5057,8 +5057,41 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
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)
{
@@ -5083,7 +5116,22 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
case ITEM_CAST_CHAR:
{
CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection);
- 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 (thd->mem_root) Item_char_typecast(a, len, real_cs);
break;
}