summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.h
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2016-09-22 07:00:10 +0400
committerAlexander Barkov <bar@mariadb.org>2016-09-22 07:00:10 +0400
commit7e4eb990adb71920cc10393194d7317ba07e3f91 (patch)
treedd613274685ad7a468e360275e5d78ee2b868c0c /sql/item_strfunc.h
parentec7e0b7b30ecd301da5990495cdf18b39425a7c6 (diff)
downloadmariadb-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.h51
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()