summaryrefslogtreecommitdiff
path: root/sql/field.cc
diff options
context:
space:
mode:
authorunknown <cmiller@zippy.cornsilk.net>2007-08-31 15:24:43 -0400
committerunknown <cmiller@zippy.cornsilk.net>2007-08-31 15:24:43 -0400
commit13fea36d03529eefceadaa16b8a9d1faf3802eed (patch)
treea4312c3393e59c7c903a284b76a49c01dcd7bdc4 /sql/field.cc
parent898333f843b5c750b9863ea94d60ab81a9caca4e (diff)
downloadmariadb-git-13fea36d03529eefceadaa16b8a9d1faf3802eed.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. 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. 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. sql/sql_yacc.yy: Make lengths take, in addition to NUM, LONG_NUM, ULONGLONG_NUM, and DECIMAL_NUM. sql/unireg.h: Define new constant.
Diffstat (limited to 'sql/field.cc')
-rw-r--r--sql/field.cc16
1 files changed, 14 insertions, 2 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 3f74210807b..2950f349580 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -8395,8 +8395,20 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
(fld_type_modifier & NOT_NULL_FLAG) && fld_type != FIELD_TYPE_TIMESTAMP)
flags|= NO_DEFAULT_VALUE_FLAG;
- if (fld_length && !(length= (uint) atoi(fld_length)))
- fld_length= 0; /* purecov: inspected */
+ if (fld_length != 0)
+ {
+ errno= 0;
+ length= strtoul(fld_length, NULL, 10);
+ if (errno != 0)
+ {
+ my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name, MAX_FIELD_BLOBLENGTH);
+ DBUG_RETURN(TRUE);
+ }
+
+ if (length == 0)
+ fld_length= 0; /* purecov: inspected */
+ }
+
sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
switch (fld_type) {