mirror of
https://github.com/MariaDB/server.git
synced 2025-02-16 18:35:34 +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
|
8352835E 8352835E 8352835E
|
||||||
8372835E 8372835E 8372835E
|
8372835E 8372835E 8372835E
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug#11766519 - Bug#59648: MY_STRTOLL10_MB2: ASSERTION `(*ENDPTR - S) % 2 == 0' FAILED.
|
||||||
|
#
|
||||||
|
SELECT QUOTE('ƒ\');
|
||||||
|
QUOTE('ƒ\')
|
||||||
|
'ƒ\'
|
||||||
# End of 5.1 tests
|
# End of 5.1 tests
|
||||||
|
|
|
@ -990,8 +990,8 @@ old_password(name)
|
||||||
????????
|
????????
|
||||||
select quote(name) from bug20536;
|
select quote(name) from bug20536;
|
||||||
quote(name)
|
quote(name)
|
||||||
????????
|
'test1'
|
||||||
????????????????
|
'\'test\\_2\''
|
||||||
drop table bug20536;
|
drop table bug20536;
|
||||||
set names ucs2;
|
set names ucs2;
|
||||||
ERROR 42000: Variable 'character_set_client' can't be set to the value of '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));
|
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))
|
HEX(CHAR(COALESCE(NULL, CHAR(COUNT('%s') USING ucs2), 1, @@global.license, NULL) USING cp850))
|
||||||
00
|
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
|
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);
|
SELECT hex(a), hex(lower(a)), hex(upper(a)) FROM t1 ORDER BY binary(a);
|
||||||
DROP TABLE t1;
|
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
|
--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 # Bug#59648 my_strtoll10_mb2: Assertion `(*endptr - s) % 2 == 0' failed.
|
||||||
--echo #
|
--echo #
|
||||||
SELECT HEX(CHAR(COALESCE(NULL, CHAR(COUNT('%s') USING ucs2), 1, @@global.license, NULL) USING cp850));
|
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
|
--echo End of 5.0 tests
|
||||||
|
|
|
@ -3214,14 +3214,68 @@ String *Item_func_quote::val_str(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_length= arg->length();
|
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++)
|
if (collation.collation->mbmaxlen == 1)
|
||||||
new_length+= get_esc_bit(escmask, (uchar) *from);
|
{
|
||||||
|
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))
|
if (tmp_value.alloc(new_length))
|
||||||
goto null;
|
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
|
We replace characters from the end to the beginning
|
||||||
*/
|
*/
|
||||||
|
@ -3253,6 +3307,8 @@ String *Item_func_quote::val_str(String *str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*to= '\'';
|
*to= '\'';
|
||||||
|
|
||||||
|
ret:
|
||||||
tmp_value.length(new_length);
|
tmp_value.length(new_length);
|
||||||
tmp_value.set_charset(collation.collation);
|
tmp_value.set_charset(collation.collation);
|
||||||
null_value= 0;
|
null_value= 0;
|
||||||
|
|
|
@ -704,9 +704,10 @@ public:
|
||||||
String *val_str(String *);
|
String *val_str(String *);
|
||||||
void fix_length_and_dec()
|
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);
|
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