http://bugs.mysql.com/bug.php?id=2368

Multibyte charsets do not check that incoming data is well-formed
parent bccca8f7
#! /bin/sh
path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium_cflags $debug_cflags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs"
extra_configs="$extra_configs --with-berkeley-db --with-innodb --without-isam --with-openssl --with-raid"
. "$path/FINISH.sh"
...@@ -88,3 +88,58 @@ select s1,hex(s1),char_length(s1),octet_length(s1) from t1; ...@@ -88,3 +88,58 @@ select s1,hex(s1),char_length(s1),octet_length(s1) from t1;
s1 hex(s1) char_length(s1) octet_length(s1) s1 hex(s1) char_length(s1) octet_length(s1)
D0B0 1 2 D0B0 1 2
drop table t1; drop table t1;
create table t1 (s1 tinytext character set utf8);
insert into t1 select repeat('a',300);
Warnings:
Warning 1264 Data truncated for column 's1' at row 1
insert into t1 select repeat('',300);
Warnings:
Warning 1264 Data truncated for column 's1' at row 1
insert into t1 select repeat('a',300);
Warnings:
Warning 1264 Data truncated for column 's1' at row 1
insert into t1 select repeat('a',300);
Warnings:
Warning 1264 Data truncated for column 's1' at row 1
insert into t1 select repeat('',300);
Warnings:
Warning 1264 Data truncated for column 's1' at row 1
select hex(s1) from t1;
hex(s1)
616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161
D18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18F
61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F
D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61D18F61
D18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18FD18F
select length(s1),char_length(s1) from t1;
length(s1) char_length(s1)
255 255
254 127
255 170
255 170
254 127
drop table t1;
create table t1 (s1 text character set utf8);
insert into t1 select repeat('a',66000);
Warnings:
Warning 1264 Data truncated for column 's1' at row 1
insert into t1 select repeat('',66000);
Warnings:
Warning 1264 Data truncated for column 's1' at row 1
insert into t1 select repeat('a',66000);
Warnings:
Warning 1264 Data truncated for column 's1' at row 1
insert into t1 select repeat('a',66000);
Warnings:
Warning 1264 Data truncated for column 's1' at row 1
insert into t1 select repeat('',66000);
Warnings:
Warning 1264 Data truncated for column 's1' at row 1
select length(s1),char_length(s1) from t1;
length(s1) char_length(s1)
65535 65535
65534 32767
65535 43690
65535 43690
65534 32767
drop table t1;
...@@ -61,3 +61,22 @@ create table t1 (s1 char(1) character set utf8); ...@@ -61,3 +61,22 @@ create table t1 (s1 char(1) character set utf8);
insert into t1 values (_koi8r''); insert into t1 values (_koi8r'');
select s1,hex(s1),char_length(s1),octet_length(s1) from t1; select s1,hex(s1),char_length(s1),octet_length(s1) from t1;
drop table t1; drop table t1;
create table t1 (s1 tinytext character set utf8);
insert into t1 select repeat('a',300);
insert into t1 select repeat('',300);
insert into t1 select repeat('a',300);
insert into t1 select repeat('a',300);
insert into t1 select repeat('',300);
select hex(s1) from t1;
select length(s1),char_length(s1) from t1;
drop table t1;
create table t1 (s1 text character set utf8);
insert into t1 select repeat('a',66000);
insert into t1 select repeat('',66000);
insert into t1 select repeat('a',66000);
insert into t1 select repeat('a',66000);
insert into t1 select repeat('',66000);
select length(s1),char_length(s1) from t1;
drop table t1;
...@@ -4485,19 +4485,9 @@ void Field_blob::store_length(uint32 number) ...@@ -4485,19 +4485,9 @@ void Field_blob::store_length(uint32 number)
{ {
switch (packlength) { switch (packlength) {
case 1: case 1:
if (number > 255)
{
number=255;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
}
ptr[0]= (uchar) number; ptr[0]= (uchar) number;
break; break;
case 2: case 2:
if (number > (uint16) ~0)
{
number= (uint16) ~0;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
}
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first) if (table->db_low_byte_first)
{ {
...@@ -4508,11 +4498,6 @@ void Field_blob::store_length(uint32 number) ...@@ -4508,11 +4498,6 @@ void Field_blob::store_length(uint32 number)
shortstore(ptr,(unsigned short) number); shortstore(ptr,(unsigned short) number);
break; break;
case 3: case 3:
if (number > (uint32) (1L << 24))
{
number= (uint32) (1L << 24)-1L;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
}
int3store(ptr,number); int3store(ptr,number);
break; break;
case 4: case 4:
...@@ -4573,6 +4558,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) ...@@ -4573,6 +4558,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
bool was_conversion; bool was_conversion;
char buff[80]; char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin); String tmpstr(buff,sizeof(buff), &my_charset_bin);
uint copy_length;
uint32 not_used; uint32 not_used;
/* Convert character set if nesessary */ /* Convert character set if nesessary */
...@@ -4583,12 +4569,22 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) ...@@ -4583,12 +4569,22 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
from= tmpstr.ptr(); from= tmpstr.ptr();
length= tmpstr.length(); length= tmpstr.length();
} }
Field_blob::store_length(length);
if (was_conversion || table->copy_blobs || length <= MAX_FIELD_WIDTH) copy_length= max_data_length();
if (copy_length > length)
copy_length= length;
copy_length= field_charset->cset->wellformedlen(field_charset,
from,from+copy_length,
field_length);
if (copy_length < length)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
Field_blob::store_length(copy_length);
if (was_conversion || table->copy_blobs || copy_length <= MAX_FIELD_WIDTH)
{ // Must make a copy { // Must make a copy
if (from != value.ptr()) // For valgrind if (from != value.ptr()) // For valgrind
{ {
value.copy(from,length,charset()); value.copy(from,copy_length,charset());
from=value.ptr(); from=value.ptr();
} }
} }
......
...@@ -949,6 +949,15 @@ public: ...@@ -949,6 +949,15 @@ public:
void sort_string(char *buff,uint length); void sort_string(char *buff,uint length);
uint32 pack_length() const uint32 pack_length() const
{ return (uint32) (packlength+table->blob_ptr_size); } { return (uint32) (packlength+table->blob_ptr_size); }
uint32 max_data_length() const
{
switch (packlength) {
case 1: return 255;
case 2: return (uint32) 0xFFFFL;
case 3: return (uint32) 0xFFFFFF;
default: return (uint32) 0xFFFFFFFF;
}
}
void reset(void) { bzero(ptr, packlength+sizeof(char*)); } void reset(void) { bzero(ptr, packlength+sizeof(char*)); }
void reset_fields() { bzero((char*) &value,sizeof(value)); } void reset_fields() { bzero((char*) &value,sizeof(value)); }
void store_length(uint32 number); void store_length(uint32 number);
......
...@@ -274,18 +274,21 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)), ...@@ -274,18 +274,21 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)),
return pos ? e+2-b0 : b-b0; return pos ? e+2-b0 : b-b0;
} }
uint my_wellformedlen_mb(CHARSET_INFO *cs __attribute__((unused)), uint my_wellformedlen_mb(CHARSET_INFO *cs,
const char *b, const char *e, uint pos) const char *b, const char *e, uint pos)
{ {
uint mblen; my_wc_t wc;
const char *b0=b; int mblen;
const char *b0= b;
while (pos && b<e) while (pos)
{ {
b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1; if ((mblen= cs->cset->mb_wc(cs, &wc, b, e)) <0)
break;
b+= mblen;
pos--; pos--;
} }
return b-b0; return b - b0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment