mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 14:02:32 +01:00
3a37afec29
The bug happens because of a combination of unfortunate circumstances: 1. Arguments args[0] and args[2] of Item_func_concat point recursively (through Item_direct_view_ref's) to the same Item_func_conv_charset. Both args[0]->args[0]->ref[0] and args[2]->args[0]->ref[0] refer to this Item_func_conv_charset. 2. When Item_func_concat::args[0]->val_str() is called, Item_func_conv_charset::val_str() writes its result to Item_func_conc_charset::tmp_value. 3. Then, for optimization purposes (to avoid copying), Item_func_substr::val_str() initializes Item_func_substr::tmp_value to point to the buffer fragment owned by Item_func_conv_charset::tmp_value Item_func_substr::tmp_value is returned as a result of Item_func_concat::args[0]->val_str(). 4. Due to optimization to avoid memory reallocs, Item_func_concat::val_str() remembers the result of args[0]->val_str() in "res" and further uses "res" to collect the return value. 5. When Item_func_concat::args[2]->val_str() is called, Item_func_conv_charset::tmp_value gets overwritten (see #1), which effectively overwrites args[0]'s Item_func_substr::tmp_value (see #3), which effectively overwrites "res" (see #4). This patch does the following: a. Changes Item_func_conv_charset::val_str(String *str) to use tmp_value and str the other way around. After this change tmp_value is used to store a temporary result, while str is used to return the value. The fixes the second problem (without SUBSTR): SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub; As Item_func_concat::val_str() supplies two different buffers when calling args[0]->val_str() and args[2]->val_str(), in the new reduction the result created during args[0]->val_str() does not get overwritten by args[2]->val_str(). b. Fixing the same problem in val_str() for similar classes Item_func_to_base64 Item_func_from_base64 Item_func_weight_string Item_func_hex Item_func_unhex Item_func_quote Item_func_compress Item_func_uncompress Item_func_des_encrypt Item_func_des_decrypt Item_func_conv_charset Item_func_reverse Item_func_soundex Item_func_aes_encrypt Item_func_aes_decrypt Item_func_buffer c. Fixing Item_func::val_str_from_val_str_ascii() the same way. Now Item_str_ascii_func::ascii_buff is used for temporary value, while the parameter passed to val_str() is used to return the result. This fixes the same problem when conversion (from ASCII to e.g. UCS2) takes place. See the ctype_ucs.test for example queries that returned wrong results before the fix. d. Some Item_func descendand classes had temporary String buffers (tmp_value and tmp_str), but did not really use them. Removing these temporary buffers from: Item_func_decode_histogram Item_func_format Item_func_binlog_gtid_pos Item_func_spatial_collection: e. Removing Item_func_buffer::tmp_value, because it's not used any more. f. Renaming Item_func_[un]compress::buffer to "tmp_value", for consistency with other classes. Note, this patch does not fix the following classes (although they have a similar problem): Item_str_conv Item_func_make_set Item_char_typecast They have a complex implementations and simple swapping between "tmp_value" and "str" won't work. These classes will be fixed separately.
96 lines
2.6 KiB
Text
96 lines
2.6 KiB
Text
-- source include/have_crypt.inc
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
|
|
select length(encrypt('foo', 'ff')) <> 0;
|
|
--replace_result $1$aa$4OSUA5cjdx0RUQ08opV27/ aaqPiZY5xR5l.
|
|
|
|
create table t1 (name varchar(50), pw varchar(64));
|
|
insert into t1 values ('tom', password('my_pass'));
|
|
set @pass='my_pass';
|
|
select name from t1 where name='tom' and pw=password(@pass);
|
|
select name from t1 where name='tom' and pw=password(@undefined);
|
|
drop table t1;
|
|
|
|
# Test new and old password handling functions
|
|
|
|
select password('abc');
|
|
select password('');
|
|
select old_password('abc');
|
|
select old_password('');
|
|
select password('gabbagabbahey');
|
|
select old_password('idkfa');
|
|
select length(password('1'));
|
|
--replace_result 60 13
|
|
select length(encrypt('test'));
|
|
--replace_result \$2a\$04\$aO....................ql.D6ROU4Byvysj72xrV1ZAkrMKS8I6 aaqPiZY5xR5l.
|
|
select encrypt('test','aa');
|
|
select old_password(NULL);
|
|
select password(NULL);
|
|
set global old_passwords=on;
|
|
select password('');
|
|
select old_password('');
|
|
select password('idkfa');
|
|
select old_password('idkfa');
|
|
set old_passwords=on;
|
|
select password('idkfa');
|
|
select old_password('idkfa');
|
|
set global old_passwords=off;
|
|
select password('idkfa');
|
|
select old_password('idkfa');
|
|
|
|
# this test shows that new scrambles honor spaces in passwords:
|
|
set old_passwords=off;
|
|
select password('idkfa ');
|
|
select password('idkfa');
|
|
select password(' idkfa');
|
|
select old_password('idkfa');
|
|
select old_password(' i d k f a ');
|
|
|
|
explain extended select password('idkfa '), old_password('idkfa');
|
|
|
|
#
|
|
# Bug #13619: Crash on FreeBSD with salt like '_.'
|
|
#
|
|
--replace_column 1 #
|
|
select encrypt('1234','_.');
|
|
|
|
# End of 4.1 tests
|
|
|
|
--echo #
|
|
--echo # Bug #44767: invalid memory reads in password() and old_password()
|
|
--echo # functions
|
|
--echo #
|
|
|
|
CREATE TABLE t1(c1 MEDIUMBLOB);
|
|
INSERT INTO t1 VALUES (REPEAT('a', 1024));
|
|
SELECT OLD_PASSWORD(c1), PASSWORD(c1) FROM t1;
|
|
DROP TABLE t1;
|
|
|
|
--echo End of 5.0 tests
|
|
|
|
|
|
--echo #
|
|
--echo # Start of 10.0 tests
|
|
--echo #
|
|
|
|
--echo #
|
|
--echo # MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery
|
|
--echo #
|
|
|
|
SET @save_optimizer_switch=@@optimizer_switch;
|
|
SET optimizer_switch='derived_merge=on';
|
|
# ENCRYPT() is not affected by MDEV-10306
|
|
# It already uses tmp_value only for internal purposes and
|
|
# returns the result in the String passed to val_str()
|
|
CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1);
|
|
INSERT INTO t1 VALUES('abcdefghi');
|
|
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT ENCRYPT(t,'aa') t2 FROM t1) sub;
|
|
DROP TABLE t1;
|
|
SET optimizer_switch=@save_optimizer_switch;
|
|
|
|
--echo #
|
|
--echo # End of 10.0 tests
|
|
--echo #
|