diff options
author | Tatiana A. Nurnberg <azundris@mysql.com> | 2008-11-20 15:39:39 +0100 |
---|---|---|
committer | Tatiana A. Nurnberg <azundris@mysql.com> | 2008-11-20 15:39:39 +0100 |
commit | d1e5808d7ed09b23a9b3b1720e43541efb66a08c (patch) | |
tree | a932d76e8ae3c26a374d2f58fd62b6ae5cec7acd | |
parent | 0001121ccbaf1c6b1d94648fac8e96ce5846550d (diff) | |
download | mariadb-git-d1e5808d7ed09b23a9b3b1720e43541efb66a08c.tar.gz |
Bug#39591: Crash if table comment is longer than 62 characters
It was possible to crash a mysqld build with EXTRA_DEBUG using
CREATE TABLE ... COMMENT with a specially-crafted UTF-8 string.
This CS removes the check that caused it since it no longer
applies in current servers anyway, and adds comments instead
to avoid future confusion.
-rw-r--r-- | mysql-test/r/strict.result | 7 | ||||
-rw-r--r-- | mysql-test/t/strict.test | 9 | ||||
-rw-r--r-- | sql/unireg.cc | 26 |
3 files changed, 34 insertions, 8 deletions
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 34869862a63..c31b5ea2189 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -1348,6 +1348,13 @@ t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*' drop table t1; +CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'; +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `f1` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן' +DROP TABLE t3; set sql_mode= 'traditional'; create table t1(col1 tinyint, col2 tinyint unsigned, col3 smallint, col4 smallint unsigned, diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index 2b71bf1093c..f66c2913ac9 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -1200,6 +1200,15 @@ show create table t1; drop table t1; # +# Bug #39591: Crash if table comment is longer than 62 characters +# + +#60 chars, 120 (+1) bytes (UTF-8 with 2-byte chars) +CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'; +SHOW CREATE TABLE t3; +DROP TABLE t3; + +# # Bug #26359: Strings becoming truncated and converted to numbers under STRICT mode # set sql_mode= 'traditional'; diff --git a/sql/unireg.cc b/sql/unireg.cc index b581ad4655a..f20d3e8cc6b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -143,6 +143,24 @@ bool mysql_create_frm(THD *thd, my_string file_name, (create_info->min_rows == 1) && (keys == 0)); int2store(fileinfo+28,key_info_length); + /* + This gives us the byte-position of the character at + (character-position, not byte-position) TABLE_COMMENT_MAXLEN. + The trick here is that character-positions start at 0, so the last + character in a maximum-allowed length string would be at char-pos + MAXLEN-1; charpos MAXLEN will be the position of the terminator. + Consequently, bytepos(charpos(MAXLEN)) should be equal to + comment[length] (which should also be the terminator, or at least + the first byte after the payload in the strict sense). If this is + not so (bytepos(charpos(MAXLEN)) comes /before/ the end of the + string), the string is too long. + + For additional credit, realise that UTF-8 has 1-3 bytes before 6.0, + and 1-4 bytes in 6.0 (6.0 also has UTF-32). This means that the + inlined COMMENT supposedly does not exceed 60 character plus + terminator, vulgo, 181 bytes. + */ + tmp_len= system_charset_info->cset->charpos(system_charset_info, create_info->comment.str, create_info->comment.str + @@ -165,14 +183,6 @@ bool mysql_create_frm(THD *thd, my_string file_name, strmake((char*) forminfo+47, create_info->comment.str ? create_info->comment.str : "", create_info->comment.length); forminfo[46]=(uchar) create_info->comment.length; -#ifdef EXTRA_DEBUG - /* - EXTRA_DEBUG causes strmake() to initialize its buffer behind the - payload with a magic value to detect wrong buffer-sizes. We - explicitly zero that segment again. - */ - memset((char*) forminfo+47 + forminfo[46], 0, 61 - forminfo[46]); -#endif if (my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW) || my_pwrite(file,(byte*) keybuff,key_info_length, (ulong) uint2korr(fileinfo+6),MYF_RW)) |