diff options
author | unknown <monty@mysql.com> | 2004-02-09 12:35:01 +0100 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-02-09 12:35:01 +0100 |
commit | 1c810278bd5e1d69f8612b047784e46b4ba7cd46 (patch) | |
tree | 4a48b244cf30bf5af88b92e2b77f60f9cd3a6a05 /sql/field.cc | |
parent | 35b1f5445056951dda823b6ec4ee6f06ca612714 (diff) | |
parent | faa8a41b1db57e643617eda8c49803f6e1287f87 (diff) | |
download | mariadb-git-1c810278bd5e1d69f8612b047784e46b4ba7cd46.tar.gz |
merge
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/sql/field.cc b/sql/field.cc index f337f4ca46c..6f29737e4a0 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4061,6 +4061,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) uint32 not_used; char buff[80]; String tmpstr(buff,sizeof(buff), &my_charset_bin); + uint copy_length; /* Convert character set if nesessary */ if (String::needs_conversion(length, cs, field_charset, ¬_used)) @@ -4069,27 +4070,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; |