Commit 790edf00 authored by Gleb Shchepa's avatar Gleb Shchepa
Browse files

backport 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.
parent 69a1c78e
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -78,3 +78,34 @@ alter table t1 modify a varchar(255);
select length(a) from t1;
length(a)
6
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'
+28 −0
Original line number Diff line number Diff line
@@ -84,3 +84,31 @@ select length(a) from t1;
alter table t1 modify a varchar(255);
select length(a) from t1;

#
# 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;
+18 −11
Original line number Diff line number Diff line
@@ -5013,6 +5013,9 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length)
  if (!ptr)
    return;
  str_value.set(ptr, max_length, &my_charset_bin);

  if (max_length > 0)
  {
    ptr+= max_length - 1;
    ptr[1]= 0;                     // Set end null for string
    for (; end >= str; end--)
@@ -5028,6 +5031,10 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length)
      power<<= 1;
    }
    *ptr= (char) bits;
  }
  else
    ptr[0]= 0;

  collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
  fixed= 1;
}