diff options
author | unknown <bar@bar.intranet.mysql.r18.ru> | 2004-02-06 16:59:25 +0400 |
---|---|---|
committer | unknown <bar@bar.intranet.mysql.r18.ru> | 2004-02-06 16:59:25 +0400 |
commit | faa8a41b1db57e643617eda8c49803f6e1287f87 (patch) | |
tree | 1de54a5d40a817616ee8991ff03ebb355c4f1d18 /sql/field.cc | |
parent | e5ab70702c082c77401052f940b18b5f6d50a8c3 (diff) | |
download | mariadb-git-faa8a41b1db57e643617eda8c49803f6e1287f87.tar.gz |
Problem fix:
http://bugs.mysql.com/bug.php?id=2366
Wrong utf8 behaviour when data is trancated
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/sql/field.cc b/sql/field.cc index 9f25b770ab0..57b77693275 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4060,6 +4060,8 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) int error= 0; char buff[80]; String tmpstr(buff,sizeof(buff), &my_charset_bin); + uint copy_length; + /* Convert character set if nesessary */ if (String::needs_conversion(from, length, cs, field_charset)) { @@ -4067,27 +4069,31 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) from= tmpstr.ptr(); length= tmpstr.length(); } - if (length <= field_length) - { - memcpy(ptr,from,length); - if (length < field_length) - field_charset->cset->fill(field_charset,ptr+length,field_length-length, - ' '); - } - else - { - memcpy(ptr,from,field_length); - if (current_thd->count_cuted_fields) - { // Check if we loosed some info - const char *end=from+length; - from+= field_length; - from+= field_charset->cset->scan(field_charset, from, end, - MY_SEQ_SPACES); - if (from != end) - { - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); - error=1; - } + + /* + Make sure we don't break a multybite sequence + as well as don't copy a malformed data. + */ + copy_length= field_charset->cset->wellformedlen(field_charset, + from,from+length, + field_length/ + field_charset->mbmaxlen); + memcpy(ptr,from,copy_length); + if (copy_length < field_length) // Append spaces if shorter + field_charset->cset->fill(field_charset,ptr+copy_length, + field_length-copy_length,' '); + + + if (current_thd->count_cuted_fields && (copy_length < length)) + { // Check if we loosed some info + const char *end=from+length; + from+= copy_length; + from+= field_charset->cset->scan(field_charset, from, end, + MY_SEQ_SPACES); + if (from != end) + { + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); + error=1; } } return error; |