Adding a new parameter for well_formed_length to

return error. We'll use it for better warnign reporting.
This commit is contained in:
bar@mysql.com 2005-04-06 11:53:15 +05:00
commit 0134a2b286
12 changed files with 57 additions and 27 deletions

View file

@ -147,7 +147,8 @@ typedef struct my_charset_handler_st
uint (*numchars)(struct charset_info_st *, const char *b, const char *e);
uint (*charpos)(struct charset_info_st *, const char *b, const char *e, uint pos);
uint (*well_formed_len)(struct charset_info_st *,
const char *b,const char *e, uint nchars);
const char *b,const char *e,
uint nchars, int *error);
uint (*lengthsp)(struct charset_info_st *, const char *ptr, uint length);
uint (*numcells)(struct charset_info_st *, const char *b, const char *e);
@ -341,7 +342,8 @@ int my_wildcmp_8bit(CHARSET_INFO *,
uint my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e);
uint my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e);
uint my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos);
uint my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos);
uint my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e,
uint pos, int *error);
int my_mbcharlen_8bit(CHARSET_INFO *, uint c);
@ -359,7 +361,8 @@ int my_wildcmp_mb(CHARSET_INFO *,
uint my_numchars_mb(CHARSET_INFO *, const char *b, const char *e);
uint my_numcells_mb(CHARSET_INFO *, const char *b, const char *e);
uint my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, uint pos);
uint my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e, uint pos);
uint my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e,
uint pos, int *error);
uint my_instr_mb(struct charset_info_st *,
const char *b, uint b_length,
const char *s, uint s_length,

View file

@ -354,12 +354,14 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
*************************************************************************/
if ((tOpType == WriteRequest)) {
if (!tAttrInfo->m_indexOnly){
int dummy_error;
// invalid data can crash kernel
if (cs != NULL &&
(*cs->cset->well_formed_len)(cs,
aValueToWrite,
aValueToWrite + sizeInBytes,
sizeInBytes) != sizeInBytes)
sizeInBytes,
&dummy_error) != sizeInBytes)
goto equal_error4;
Uint32 ahValue;
Uint32 sz = totalSizeInWords;

View file

@ -526,6 +526,7 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo,
const Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize;
CHARSET_INFO* cs = tAttrInfo->m_cs;
int dummy_error;
// invalid data can crash kernel
if (cs != NULL &&
// fast fix bug#7340
@ -533,7 +534,8 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo,
(*cs->cset->well_formed_len)(cs,
aValue,
aValue + sizeInBytes,
sizeInBytes) != sizeInBytes) {
sizeInBytes,
&dummy_error) != sizeInBytes) {
setErrorCodeAbort(744);
return -1;
}

View file

@ -226,12 +226,14 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
if ((tOpType == InsertRequest) ||
(tOpType == WriteRequest)) {
if (!tAttrInfo->m_indexOnly){
int dummy_error;
// invalid data can crash kernel
if (cs != NULL &&
(*cs->cset->well_formed_len)(cs,
aValueToWrite,
aValueToWrite + sizeInBytes,
sizeInBytes) != sizeInBytes)
sizeInBytes,
&dummy_error) != sizeInBytes)
goto equal_error4;
Uint32 ahValue;
const Uint32 sz = totalSizeInWords;

View file

@ -4939,9 +4939,10 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
as well as don't copy a malformed data.
*/
copy_length= field_charset->cset->well_formed_len(field_charset,
from,from+length,
field_length/
field_charset->mbmaxlen);
from,from+length,
field_length/
field_charset->mbmaxlen,
&error);
memcpy(ptr,from,copy_length);
if (copy_length < field_length) // Append spaces if shorter
field_charset->cset->fill(field_charset,ptr+copy_length,
@ -4958,7 +4959,6 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
}
if (error)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
return error;
}
@ -5577,9 +5577,10 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
the 'min()' call below.
*/
copy_length= field_charset->cset->well_formed_len(field_charset,
from,from +
min(length, copy_length),
copy_length);
from,from +
min(length, copy_length),
copy_length,
&error);
if (copy_length < length)
error= 1;
Field_blob::store_length(copy_length);

View file

@ -5032,9 +5032,10 @@ IDENT_sys:
if (thd->charset_is_system_charset)
{
CHARSET_INFO *cs= system_charset_info;
int dummy_error;
uint wlen= cs->cset->well_formed_len(cs, $1.str,
$1.str+$1.length,
$1.length);
$1.length, &dummy_error);
if (wlen < $1.length)
{
net_printf(YYTHD, ER_INVALID_CHARACTER_STRING, cs->csname,

View file

@ -6278,10 +6278,13 @@ my_mb_wc_big5(CHARSET_INFO *cs __attribute__((unused)),
*/
static
uint my_well_formed_len_big5(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e, uint pos)
const char *b, const char *e,
uint pos, int *error)
{
const char *b0= b;
const char *emb= e - 1; /* Last possible end of an MB character */
*error= 0;
while (pos && b < e)
{
if ((uchar) b[0] < 128)
@ -6297,6 +6300,7 @@ uint my_well_formed_len_big5(CHARSET_INFO *cs __attribute__((unused)),
else
{
/* Wrong byte sequence */
*error= 1;
break;
}
}

View file

@ -264,18 +264,21 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)),
}
uint my_well_formed_len_mb(CHARSET_INFO *cs,
const char *b, const char *e, uint pos)
uint my_well_formed_len_mb(CHARSET_INFO *cs, const char *b, const char *e,
uint pos, int *error)
{
const char *b_start= b;
*error= 0;
while (pos)
{
my_wc_t wc;
int mblen;
if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0)
{
*error= 1;
break;
}
b+= mblen;
pos--;
}

View file

@ -1093,11 +1093,11 @@ uint my_charpos_8bit(CHARSET_INFO *cs __attribute__((unused)),
uint my_well_formed_len_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *start,
const char *end,
uint nchars)
const char *start, const char *end,
uint nchars, int *error)
{
uint nbytes= (uint) (end-start);
*error= 0;
return min(nbytes, nchars);
}

View file

@ -4571,9 +4571,11 @@ uint my_numcells_sjis(CHARSET_INFO *cs __attribute__((unused)),
*/
static
uint my_well_formed_len_sjis(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e, uint pos)
const char *b, const char *e,
uint pos, int *error)
{
const char *b0= b;
*error= 0;
while (pos && b < e)
{
if ((uchar) b[0] < 128)
@ -4594,6 +4596,7 @@ uint my_well_formed_len_sjis(CHARSET_INFO *cs __attribute__((unused)),
else
{
/* Wrong byte sequence */
*error= 1;
break;
}
}

View file

@ -1267,11 +1267,11 @@ uint my_charpos_ucs2(CHARSET_INFO *cs __attribute__((unused)),
static
uint my_well_formed_len_ucs2(CHARSET_INFO *cs __attribute__((unused)),
const char *b,
const char *e,
uint nchars)
const char *b, const char *e,
uint nchars, int *error)
{
uint nbytes= (e-b) & ~ (uint)1;
*error= 0;
nchars*= 2;
return min(nbytes, nchars);
}

View file

@ -8253,11 +8253,12 @@ my_jisx0212_uni_onechar(int code){
static
uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)),
const char *beg, const char *end, uint pos)
const char *beg, const char *end,
uint pos, int *error)
{
const uchar *b= (uchar *) beg;
for ( ; pos && b < (uchar*) end; pos--, b++)
for ( *error= 0 ; pos && b < (uchar*) end; pos--, b++)
{
char *chbeg;
uint ch= *b;
@ -8267,12 +8268,16 @@ uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)),
chbeg= (char *) b++;
if (b >= (uchar *) end) /* need more bytes */
{
*error= 1;
return chbeg - beg; /* unexpected EOL */
}
if (ch == 0x8E) /* [x8E][xA0-xDF] */
{
if (*b >= 0xA0 && *b <= 0xDF)
continue;
*error= 1;
return chbeg - beg; /* invalid sequence */
}
@ -8280,12 +8285,16 @@ uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)),
{
ch= *b++;
if (b >= (uchar*) end)
{
*error= 1;
return chbeg - beg; /* unexpected EOL */
}
}
if (ch >= 0xA1 && ch <= 0xFE &&
*b >= 0xA1 && *b <= 0xFE) /* [xA1-xFE][xA1-xFE] */
continue;
*error= 1;
return chbeg - beg; /* invalid sequence */
}
return b - (uchar *) beg;