diff options
author | Alexander Barkov <bar@mariadb.org> | 2016-09-22 07:00:10 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2016-09-22 07:00:10 +0400 |
commit | 7e4eb990adb71920cc10393194d7317ba07e3f91 (patch) | |
tree | dd613274685ad7a468e360275e5d78ee2b868c0c /sql/item_strfunc.h | |
parent | ec7e0b7b30ecd301da5990495cdf18b39425a7c6 (diff) | |
download | mariadb-git-7e4eb990adb71920cc10393194d7317ba07e3f91.tar.gz |
MDEV-10425 Assertion `collation.derivation == DERIVATION_IMPLICIT' failed in Item_func_conv_charset::fix_length_and_dec()
MDEV-10850 Wrong result for WHERE .. (f2=TO_BASE64('test') OR f2=TO_BASE64('TEST'))
Problem N1: MDEV-10425
Item_func_{md5|sha|sha2}::fix_length_and_dec() changed args[0]->collation
to force binary comparison in args[0]->eq().
It was done to treat e.g. MD5('a') and MD5('A') as different values.
It is wrong for a Item_func_xxx to modify its arguments.
Item_func_conv_charset did not expect that and crashed on assert.
Problem N2: MDEV-10850
Item_func_to_base64, Item_func_password, Item_func_hex are also case sensitive
hash functions, but they did not compare their arguments as binary.
Solution:
- Removing the code changing args[0]->collation
- Introducing Item_str_ascii_checksum_func as a common parent
for Item_func_{md5|sha|sha2|password|hex|to_base64}
and overriding its eq() method to compare arguments binary.
Diffstat (limited to 'sql/item_strfunc.h')
-rw-r--r-- | sql/item_strfunc.h | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 65c286819d3..db0509e17d7 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -96,40 +96,63 @@ public: }; -class Item_func_md5 :public Item_str_ascii_func +/** + Functions returning a checksum or a hash of the argument. +*/ +class Item_str_ascii_checksum_func: public Item_str_ascii_func +{ +public: + Item_str_ascii_checksum_func(THD *thd, Item *a) + :Item_str_ascii_func(thd, a) { } + Item_str_ascii_checksum_func(THD *thd, Item *a, Item *b) + :Item_str_ascii_func(thd, a, b) { } + bool eq(const Item *item, bool binary_cmp) const + { + // Always use binary argument comparison: MD5('x') != MD5('X') + return Item_func::eq(item, true); + } +}; + + +class Item_func_md5 :public Item_str_ascii_checksum_func { String tmp_value; public: - Item_func_md5(THD *thd, Item *a): Item_str_ascii_func(thd, a) {} + Item_func_md5(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {} String *val_str_ascii(String *); - void fix_length_and_dec(); + void fix_length_and_dec() + { + fix_length_and_charset(32, default_charset()); + } const char *func_name() const { return "md5"; } }; -class Item_func_sha :public Item_str_ascii_func +class Item_func_sha :public Item_str_ascii_checksum_func { public: - Item_func_sha(THD *thd, Item *a): Item_str_ascii_func(thd, a) {} + Item_func_sha(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {} String *val_str_ascii(String *); void fix_length_and_dec(); const char *func_name() const { return "sha"; } }; -class Item_func_sha2 :public Item_str_ascii_func +class Item_func_sha2 :public Item_str_ascii_checksum_func { public: - Item_func_sha2(THD *thd, Item *a, Item *b): Item_str_ascii_func(thd, a, b) {} + Item_func_sha2(THD *thd, Item *a, Item *b) + :Item_str_ascii_checksum_func(thd, a, b) {} String *val_str_ascii(String *); void fix_length_and_dec(); const char *func_name() const { return "sha2"; } }; -class Item_func_to_base64 :public Item_str_ascii_func +class Item_func_to_base64 :public Item_str_ascii_checksum_func { String tmp_value; public: - Item_func_to_base64(THD *thd, Item *a): Item_str_ascii_func(thd, a) {} + Item_func_to_base64(THD *thd, Item *a) + :Item_str_ascii_checksum_func(thd, a) {} String *val_str_ascii(String *); void fix_length_and_dec(); const char *func_name() const { return "to_base64"; } @@ -431,7 +454,7 @@ public: authentication procedure works, see comments in password.c. */ -class Item_func_password :public Item_str_ascii_func +class Item_func_password :public Item_str_ascii_checksum_func { public: enum PW_Alg {OLD, NEW}; @@ -441,9 +464,9 @@ private: bool deflt; public: Item_func_password(THD *thd, Item *a): - Item_str_ascii_func(thd, a), alg(NEW), deflt(1) {} + Item_str_ascii_checksum_func(thd, a), alg(NEW), deflt(1) {} Item_func_password(THD *thd, Item *a, PW_Alg al): - Item_str_ascii_func(thd, a), alg(al), deflt(0) {} + Item_str_ascii_checksum_func(thd, a), alg(al), deflt(0) {} String *val_str_ascii(String *str); bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec() @@ -803,12 +826,12 @@ public: }; -class Item_func_hex :public Item_str_ascii_func +class Item_func_hex :public Item_str_ascii_checksum_func { String tmp_value; public: Item_func_hex(THD *thd, Item *a): - Item_str_ascii_func(thd, a) {} + Item_str_ascii_checksum_func(thd, a) {} const char *func_name() const { return "hex"; } String *val_str_ascii(String *); void fix_length_and_dec() |