Skip to content

Commit 7e96949

Browse files
Bug #19514067 CRASH WHEN SETTING
SESSION_TRACK_SYSTEM_VARIABLES Problem: When session_track_system_variables is set with NULL, it doesn't clear the previous value from the hash which is present to maintain the value of string variables. Solution: Added code to remove the existing value from the hash when set with NULL.
1 parent 51b4f31 commit 7e96949

File tree

1 file changed

+54
-20
lines changed

1 file changed

+54
-20
lines changed

sql/sys_vars_resource_mgr.cc

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,14 @@ bool Session_sysvar_resource_manager::init(char **var, const CHARSET_INFO * char
9191
bool Session_sysvar_resource_manager::update(char **var, char *val,
9292
size_t val_len)
9393
{
94-
sys_var_ptr *element;
95-
char *ptr;
96-
94+
sys_var_ptr *element= NULL;
95+
char *ptr= NULL;
96+
char *old_key= NULL;
97+
98+
/*
99+
Memory allocation for the new value of the variable and
100+
copying the value in it.
101+
*/
97102
if (val)
98103
{
99104
if ( !(ptr=
@@ -102,13 +107,47 @@ bool Session_sysvar_resource_manager::update(char **var, char *val,
102107
return true;
103108
ptr[val_len]= 0;
104109
}
105-
else
110+
111+
/* Get the handle for existing value in hash. */
112+
if (*var)
113+
{
114+
element= (sys_var_ptr *) find(*var, strlen(*var));
115+
if (element)
116+
old_key= (char *) element->data;
117+
}
118+
119+
/*
120+
Update the value in hash when both the existing value
121+
and the new value are not null.
122+
*/
123+
if (val && *var)
124+
{
125+
/* Free the existing one & update the current address. */
126+
element->data= (char *) ptr;
127+
my_hash_update(&m_sysvar_string_alloc_hash, (uchar *) element,
128+
(uchar *)old_key, strlen(old_key));
129+
if (old_key)
130+
my_free(old_key);
131+
}
132+
133+
/*
134+
Delete the existing value from the hash when the new value is NULL.
135+
*/
136+
else if ((val == NULL) && *var)
106137
{
107-
ptr= 0;
108-
goto done;
138+
if (element)
139+
{
140+
my_hash_delete(&m_sysvar_string_alloc_hash, (uchar *)element);
141+
if (old_key)
142+
my_free(old_key);
143+
}
109144
}
110145

111-
if (!(*var && (element= ((sys_var_ptr *)find(*var, strlen(*var))))))
146+
/*
147+
Insert the new value into the hash when it is not NULL, but the
148+
existing value is.
149+
*/
150+
else if ((*var == NULL) && val)
112151
{
113152
/* Create a new node & add it to the list. */
114153
if( !(element=
@@ -118,19 +157,14 @@ bool Session_sysvar_resource_manager::update(char **var, char *val,
118157
element->data= (char *) ptr;
119158
my_hash_insert(&m_sysvar_string_alloc_hash, (uchar *) element);
120159
}
121-
else
122-
{
123-
/* Free the existing one & update the current address. */
124-
char *old_key;
125-
old_key= (char *) element->data;
126-
element->data= (char *) ptr;
127-
my_hash_update(&m_sysvar_string_alloc_hash, (uchar *) element,
128-
(uchar *)old_key, strlen(old_key));
129-
if (old_key)
130-
my_free(old_key);
131-
}
132-
done:
133-
/* Update the variable to point to the newly alloced copy. */
160+
161+
/*
162+
Update the variable to point to the newly alloced copy.
163+
164+
When current value and the new value are both NULL,
165+
the control directly reaches here. In that case this
166+
function effectively does nothing.
167+
*/
134168
*var= ptr;
135169
return false;
136170
}

0 commit comments

Comments
 (0)