mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 10:14:19 +01:00
Bug 11766519 - 59648: MY_STRTOLL10_MB2: ASSERTION `(*ENDPTR - S) % 2 == 0' FAILED.
Part 2. Function QUOTE() was not multi-byte safe. @ mysql-test/r/ctype_ucs.result @ mysql-test/t/ctype_ucs.test Adding tests @ sql/item_strfunc.cc Fixing Item_func_quote::val_str to be multi-byte safe. @ sql/item_strfunc.h Multiple size needed for quote characters to mbmaxlen
This commit is contained in:
parent
1bc5e76efb
commit
a1e9be8e8b
6 changed files with 84 additions and 7 deletions
|
@ -218,4 +218,10 @@ hex(a) hex(lower(a)) hex(upper(a))
|
|||
8352835E 8352835E 8352835E
|
||||
8372835E 8372835E 8372835E
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#11766519 - Bug#59648: MY_STRTOLL10_MB2: ASSERTION `(*ENDPTR - S) % 2 == 0' FAILED.
|
||||
#
|
||||
SELECT QUOTE('ƒ\');
|
||||
QUOTE('ƒ\')
|
||||
'ƒ\'
|
||||
# End of 5.1 tests
|
||||
|
|
|
@ -990,8 +990,8 @@ old_password(name)
|
|||
????????
|
||||
select quote(name) from bug20536;
|
||||
quote(name)
|
||||
????????
|
||||
????????????????
|
||||
'test1'
|
||||
'\'test\\_2\''
|
||||
drop table bug20536;
|
||||
set names ucs2;
|
||||
ERROR 42000: Variable 'character_set_client' can't be set to the value of 'ucs2'
|
||||
|
@ -1244,4 +1244,9 @@ DROP TABLE t1;
|
|||
SELECT HEX(CHAR(COALESCE(NULL, CHAR(COUNT('%s') USING ucs2), 1, @@global.license, NULL) USING cp850));
|
||||
HEX(CHAR(COALESCE(NULL, CHAR(COUNT('%s') USING ucs2), 1, @@global.license, NULL) USING cp850))
|
||||
00
|
||||
SELECT CONVERT(QUOTE(CHAR(0xf5 using ucs2)), SIGNED);
|
||||
CONVERT(QUOTE(CHAR(0xf5 using ucs2)), SIGNED)
|
||||
0
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect INTEGER value: ''
|
||||
End of 5.0 tests
|
||||
|
|
|
@ -92,4 +92,12 @@ INSERT INTO t1 VALUES (0x8372835E),(0x8352835E);
|
|||
SELECT hex(a), hex(lower(a)), hex(upper(a)) FROM t1 ORDER BY binary(a);
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#11766519 - Bug#59648: MY_STRTOLL10_MB2: ASSERTION `(*ENDPTR - S) % 2 == 0' FAILED.
|
||||
--echo #
|
||||
# In the below string backslash (0x5C) is a part of a multi-byte
|
||||
# character, so it should not be quoted.
|
||||
SELECT QUOTE('ƒ\');
|
||||
|
||||
|
||||
--echo # End of 5.1 tests
|
||||
|
|
|
@ -745,5 +745,6 @@ DROP TABLE t1;
|
|||
--echo # Bug#59648 my_strtoll10_mb2: Assertion `(*endptr - s) % 2 == 0' failed.
|
||||
--echo #
|
||||
SELECT HEX(CHAR(COALESCE(NULL, CHAR(COUNT('%s') USING ucs2), 1, @@global.license, NULL) USING cp850));
|
||||
SELECT CONVERT(QUOTE(CHAR(0xf5 using ucs2)), SIGNED);
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
|
|
@ -3214,14 +3214,68 @@ String *Item_func_quote::val_str(String *str)
|
|||
}
|
||||
|
||||
arg_length= arg->length();
|
||||
new_length= arg_length+2; /* for beginning and ending ' signs */
|
||||
|
||||
for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
|
||||
new_length+= get_esc_bit(escmask, (uchar) *from);
|
||||
if (collation.collation->mbmaxlen == 1)
|
||||
{
|
||||
new_length= arg_length + 2; /* for beginning and ending ' signs */
|
||||
for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
|
||||
new_length+= get_esc_bit(escmask, (uchar) *from);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_length= (arg_length * 2) + /* For string characters */
|
||||
(2 * collation.collation->mbmaxlen); /* For quotes */
|
||||
}
|
||||
|
||||
if (tmp_value.alloc(new_length))
|
||||
goto null;
|
||||
|
||||
if (collation.collation->mbmaxlen > 1)
|
||||
{
|
||||
CHARSET_INFO *cs= collation.collation;
|
||||
int mblen;
|
||||
uchar *to_end;
|
||||
to= (char*) tmp_value.ptr();
|
||||
to_end= (uchar*) to + new_length;
|
||||
|
||||
/* Put leading quote */
|
||||
if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
|
||||
goto null;
|
||||
to+= mblen;
|
||||
|
||||
for (start= (char*) arg->ptr(), end= start + arg_length; start < end; )
|
||||
{
|
||||
my_wc_t wc;
|
||||
bool escape;
|
||||
if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) start, (uchar*) end)) <= 0)
|
||||
goto null;
|
||||
start+= mblen;
|
||||
switch (wc) {
|
||||
case 0: escape= 1; wc= '0'; break;
|
||||
case '\032': escape= 1; wc= 'Z'; break;
|
||||
case '\'': escape= 1; break;
|
||||
case '\\': escape= 1; break;
|
||||
default: escape= 0; break;
|
||||
}
|
||||
if (escape)
|
||||
{
|
||||
if ((mblen= cs->cset->wc_mb(cs, '\\', (uchar*) to, to_end)) <= 0)
|
||||
goto null;
|
||||
to+= mblen;
|
||||
}
|
||||
if ((mblen= cs->cset->wc_mb(cs, wc, (uchar*) to, to_end)) <= 0)
|
||||
goto null;
|
||||
to+= mblen;
|
||||
}
|
||||
|
||||
/* Put trailing quote */
|
||||
if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
|
||||
goto null;
|
||||
to+= mblen;
|
||||
new_length= to - tmp_value.ptr();
|
||||
goto ret;
|
||||
}
|
||||
|
||||
/*
|
||||
We replace characters from the end to the beginning
|
||||
*/
|
||||
|
@ -3253,6 +3307,8 @@ String *Item_func_quote::val_str(String *str)
|
|||
}
|
||||
}
|
||||
*to= '\'';
|
||||
|
||||
ret:
|
||||
tmp_value.length(new_length);
|
||||
tmp_value.set_charset(collation.collation);
|
||||
null_value= 0;
|
||||
|
|
|
@ -704,9 +704,10 @@ public:
|
|||
String *val_str(String *);
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 + 2;
|
||||
max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
|
||||
collation.set(args[0]->collation);
|
||||
ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
|
||||
2 * collation.collation->mbmaxlen;
|
||||
max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue