summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Shchepa <gshchepa@mysql.com>2008-06-27 18:22:23 +0500
committerGleb Shchepa <gshchepa@mysql.com>2008-06-27 18:22:23 +0500
commitdc0e959a302d55825b6204c1cce63d7d73fd5b93 (patch)
tree8ac8fc9ad8267766f73449691b92aea676f0f6f6
parent98cf483064d1f176dc0d8219ac6563049de708b0 (diff)
downloadmariadb-git-dc0e959a302d55825b6204c1cce63d7d73fd5b93.tar.gz
buckport to 5.1.26 from 6.0
Bug#35658 (An empty binary value leads to mysqld crash) Before this fix, the following token b'' caused the parser to crash when reading the binary value from the empty string. The crash was caused by: ptr+= max_length - 1; because max_length is unsigned and was 0, causing an overflow. With this fix, an empty binary literal b'' is parsed as a binary value 0, in Item_bin_string. mysql-test/r/varbinary.result: Bug#35658 (An empty binary value leads to mysqld crash) mysql-test/t/varbinary.test: Bug#35658 (An empty binary value leads to mysqld crash) sql/item.cc: Bug#35658 (An empty binary value leads to mysqld crash)
-rw-r--r--mysql-test/r/varbinary.result31
-rw-r--r--mysql-test/t/varbinary.test28
-rw-r--r--sql/item.cc29
3 files changed, 77 insertions, 11 deletions
diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result
index 6d39d8301c5..271d7a0fe8d 100644
--- a/mysql-test/r/varbinary.result
+++ b/mysql-test/r/varbinary.result
@@ -95,3 +95,34 @@ table_28127_b CREATE TABLE `table_28127_b` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table table_28127_a;
drop table table_28127_b;
+select 0b01000001;
+0b01000001
+A
+select 0x41;
+0x41
+A
+select b'01000001';
+b'01000001'
+A
+select x'41', 0+x'41';
+x'41' 0+x'41'
+A 65
+select N'abc', length(N'abc');
+abc length(N'abc')
+abc 3
+select N'', length(N'');
+ length(N'')
+ 0
+select '', length('');
+ length('')
+ 0
+select b'', 0+b'';
+b'' 0+b''
+ 0
+select x'', 0+x'';
+x'' 0+x''
+ 0
+select 0x;
+ERROR 42S22: Unknown column '0x' in 'field list'
+select 0b;
+ERROR 42S22: Unknown column '0b' in 'field list'
diff --git a/mysql-test/t/varbinary.test b/mysql-test/t/varbinary.test
index 9ccbac7cdda..1db561183a7 100644
--- a/mysql-test/t/varbinary.test
+++ b/mysql-test/t/varbinary.test
@@ -104,3 +104,31 @@ show create table table_28127_b;
drop table table_28127_a;
drop table table_28127_b;
+#
+# Bug#35658 (An empty binary value leads to mysqld crash)
+#
+
+select 0b01000001;
+
+select 0x41;
+
+select b'01000001';
+
+select x'41', 0+x'41';
+
+select N'abc', length(N'abc');
+
+select N'', length(N'');
+
+select '', length('');
+
+select b'', 0+b'';
+
+select x'', 0+x'';
+
+--error ER_BAD_FIELD_ERROR
+select 0x;
+
+--error ER_BAD_FIELD_ERROR
+select 0b;
+
diff --git a/sql/item.cc b/sql/item.cc
index 96408a70bdd..5ee394fcbe0 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5172,21 +5172,28 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length)
if (!ptr)
return;
str_value.set(ptr, max_length, &my_charset_bin);
- ptr+= max_length - 1;
- ptr[1]= 0; // Set end null for string
- for (; end >= str; end--)
+
+ if (max_length > 0)
{
- if (power == 256)
+ ptr+= max_length - 1;
+ ptr[1]= 0; // Set end null for string
+ for (; end >= str; end--)
{
- power= 1;
- *ptr--= bits;
- bits= 0;
+ if (power == 256)
+ {
+ power= 1;
+ *ptr--= bits;
+ bits= 0;
+ }
+ if (*end == '1')
+ bits|= power;
+ power<<= 1;
}
- if (*end == '1')
- bits|= power;
- power<<= 1;
+ *ptr= (char) bits;
}
- *ptr= (char) bits;
+ else
+ ptr[0]= 0;
+
collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
fixed= 1;
}