Skip to content

Commit 529de87

Browse files
author
Tor Didriksen
committed
Bug#21819304 CRASH IF STORING DECIMAL DATA IN USER VARIABLES
This is a backport of Bug#18563112 SELECT INTO VARIABLE CRASH IN USER_VAR_ENTRY::STORE In Item_func_set_user_var::update_hash: call entry->set_null_value() rather than entry->store() for NULL input.
1 parent a0bc9d8 commit 529de87

File tree

3 files changed

+21
-13
lines changed

3 files changed

+21
-13
lines changed

sql/item_func.cc

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4729,7 +4729,7 @@ bool user_var_entry::realloc(uint length)
47294729
@retval true on allocation error
47304730
47314731
*/
4732-
bool user_var_entry::store(void *from, uint length, Item_result type)
4732+
bool user_var_entry::store(const void *from, uint length, Item_result type)
47334733
{
47344734
// Store strings with end \0
47354735
if (realloc(length + MY_TEST(type == STRING_RESULT)))
@@ -4763,7 +4763,7 @@ bool user_var_entry::store(void *from, uint length, Item_result type)
47634763
true failure
47644764
*/
47654765

4766-
bool user_var_entry::store(void *ptr, uint length, Item_result type,
4766+
bool user_var_entry::store(const void *ptr, uint length, Item_result type,
47674767
const CHARSET_INFO *cs, Derivation dv,
47684768
bool unsigned_arg)
47694769
{
@@ -4776,7 +4776,7 @@ bool user_var_entry::store(void *ptr, uint length, Item_result type,
47764776

47774777

47784778
bool
4779-
Item_func_set_user_var::update_hash(void *ptr, uint length,
4779+
Item_func_set_user_var::update_hash(const void *ptr, uint length,
47804780
Item_result res_type,
47814781
const CHARSET_INFO *cs, Derivation dv,
47824782
bool unsigned_arg)
@@ -4790,8 +4790,16 @@ Item_func_set_user_var::update_hash(void *ptr, uint length,
47904790
null_value= ((Item_field*)args[0])->field->is_null();
47914791
else
47924792
null_value= args[0]->null_value;
4793+
4794+
if (ptr == NULL)
4795+
{
4796+
DBUG_ASSERT(length == 0);
4797+
null_value= true;
4798+
}
4799+
47934800
if (null_value && null_item)
47944801
res_type= entry->type(); // Don't change type of item
4802+
47954803
if (null_value)
47964804
entry->set_null_value(res_type);
47974805
else if (entry->store(ptr, length, res_type, cs, dv, unsigned_arg))
@@ -5046,24 +5054,24 @@ Item_func_set_user_var::update()
50465054
switch (cached_result_type) {
50475055
case REAL_RESULT:
50485056
{
5049-
res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
5057+
res= update_hash(&save_result.vreal,sizeof(save_result.vreal),
50505058
REAL_RESULT, default_charset(), DERIVATION_IMPLICIT, 0);
50515059
break;
50525060
}
50535061
case INT_RESULT:
50545062
{
5055-
res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
5063+
res= update_hash(&save_result.vint, sizeof(save_result.vint),
50565064
INT_RESULT, default_charset(), DERIVATION_IMPLICIT,
50575065
unsigned_flag);
50585066
break;
50595067
}
50605068
case STRING_RESULT:
50615069
{
50625070
if (!save_result.vstr) // Null value
5063-
res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
5071+
res= update_hash(NULL, 0, STRING_RESULT, &my_charset_bin,
50645072
DERIVATION_IMPLICIT, 0);
50655073
else
5066-
res= update_hash((void*) save_result.vstr->ptr(),
5074+
res= update_hash(save_result.vstr->ptr(),
50675075
save_result.vstr->length(), STRING_RESULT,
50685076
save_result.vstr->charset(),
50695077
DERIVATION_IMPLICIT, 0);
@@ -5072,10 +5080,10 @@ Item_func_set_user_var::update()
50725080
case DECIMAL_RESULT:
50735081
{
50745082
if (!save_result.vdec) // Null value
5075-
res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
5083+
res= update_hash(NULL, 0, DECIMAL_RESULT, &my_charset_bin,
50765084
DERIVATION_IMPLICIT, 0);
50775085
else
5078-
res= update_hash((void*) save_result.vdec,
5086+
res= update_hash(save_result.vdec,
50795087
sizeof(my_decimal), DECIMAL_RESULT,
50805088
default_charset(), DERIVATION_IMPLICIT, 0);
50815089
break;

sql/item_func.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef ITEM_FUNC_INCLUDED
22
#define ITEM_FUNC_INCLUDED
33

4-
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
4+
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
55
66
This program is free software; you can redistribute it and/or modify
77
it under the terms of the GNU General Public License as published by
@@ -1700,7 +1700,7 @@ class Item_func_set_user_var :public Item_var_func
17001700
String *str_result(String *str);
17011701
my_decimal *val_decimal_result(my_decimal *);
17021702
bool is_null_result();
1703-
bool update_hash(void *ptr, uint length, enum Item_result type,
1703+
bool update_hash(const void *ptr, uint length, enum Item_result type,
17041704
const CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
17051705
bool send(Protocol *protocol, String *str_arg);
17061706
void make_field(Send_field *tmp_field);

sql/sql_class.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4939,7 +4939,7 @@ class user_var_entry
49394939
@retval false on success
49404940
@retval true on memory allocation error
49414941
*/
4942-
bool store(void *from, uint length, Item_result type);
4942+
bool store(const void *from, uint length, Item_result type);
49434943

49444944
public:
49454945
user_var_entry() {} /* Remove gcc warning */
@@ -4962,7 +4962,7 @@ class user_var_entry
49624962
@retval false on success
49634963
@retval true on memory allocation error
49644964
*/
4965-
bool store(void *from, uint length, Item_result type,
4965+
bool store(const void *from, uint length, Item_result type,
49664966
const CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
49674967
/**
49684968
Set type of to the given value.

0 commit comments

Comments
 (0)