Commit 3711e24a authored by unknown's avatar unknown

Fix for #1429 (Segfault in mysql_stmt_close)

Problem was that we checked for existing connection in stmt_close
and did not free(stmt) if it's closed (that didn't work well with
embedded)
I just added new flag to the stmt_close and now we check it instead
of connection


libmysql/client_settings.h:
  declaration changed
libmysql/libmysql.c:
  stmt_close and it's calls modified
sql-common/client.c:
  stmt_close call modified
parent 38042001
...@@ -22,7 +22,7 @@ extern my_string mysql_unix_port; ...@@ -22,7 +22,7 @@ extern my_string mysql_unix_port;
CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION) CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION)
sig_handler pipe_sig_handler(int sig __attribute__((unused))); sig_handler pipe_sig_handler(int sig __attribute__((unused)));
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list); my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list, my_bool skip_free);
void read_user_name(char *name); void read_user_name(char *name);
my_bool send_file_to_server(MYSQL *mysql, const char *filename); my_bool send_file_to_server(MYSQL *mysql, const char *filename);
......
...@@ -89,7 +89,7 @@ static void append_wild(char *to,char *end,const char *wild); ...@@ -89,7 +89,7 @@ static void append_wild(char *to,char *end,const char *wild);
sig_handler pipe_sig_handler(int sig); sig_handler pipe_sig_handler(int sig);
static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
const char *from, ulong length); const char *from, ulong length);
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list); my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list, my_bool skip_free);
static my_bool mysql_client_init= 0; static my_bool mysql_client_init= 0;
static my_bool org_my_init_done= 0; static my_bool org_my_init_done= 0;
...@@ -1666,14 +1666,14 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length) ...@@ -1666,14 +1666,14 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
} }
if (simple_command(mysql, COM_PREPARE, query, length, 1)) if (simple_command(mysql, COM_PREPARE, query, length, 1))
{ {
stmt_close(stmt, 1); stmt_close(stmt, 1, 0);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
init_alloc_root(&stmt->mem_root,8192,0); init_alloc_root(&stmt->mem_root,8192,0);
if ((*mysql->methods->read_prepare_result)(mysql, stmt)) if ((*mysql->methods->read_prepare_result)(mysql, stmt))
{ {
stmt_close(stmt, 1); stmt_close(stmt, 1, 0);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -3312,7 +3312,7 @@ my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt) ...@@ -3312,7 +3312,7 @@ my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt)
} }
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list) my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list, my_bool skip_free)
{ {
MYSQL *mysql; MYSQL *mysql;
DBUG_ENTER("mysql_stmt_close"); DBUG_ENTER("mysql_stmt_close");
...@@ -3321,7 +3321,8 @@ my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list) ...@@ -3321,7 +3321,8 @@ my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
if (!(mysql= stmt->mysql)) if (!(mysql= stmt->mysql))
{ {
my_free((gptr) stmt, MYF(MY_WME)); if (!skip_free)
my_free((gptr) stmt, MYF(MY_WME));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
mysql_stmt_free_result(stmt); mysql_stmt_free_result(stmt);
...@@ -3329,7 +3330,7 @@ my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list) ...@@ -3329,7 +3330,7 @@ my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
{ {
char buff[4]; char buff[4];
int4store(buff, stmt->stmt_id); int4store(buff, stmt->stmt_id);
if (simple_command(mysql, COM_CLOSE_STMT, buff, 4, 1)) if (skip_free || simple_command(mysql, COM_CLOSE_STMT, buff, 4, 1))
{ {
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno, set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
mysql->net.sqlstate); mysql->net.sqlstate);
...@@ -3350,7 +3351,7 @@ my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list) ...@@ -3350,7 +3351,7 @@ my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt) my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
{ {
return stmt_close(stmt, 0); return stmt_close(stmt, 0, 0);
} }
/* /*
......
...@@ -2197,7 +2197,7 @@ void STDCALL mysql_close(MYSQL *mysql) ...@@ -2197,7 +2197,7 @@ void STDCALL mysql_close(MYSQL *mysql)
for (element= mysql->stmts; element; element= next_element) for (element= mysql->stmts; element; element= next_element)
{ {
next_element= element->next; next_element= element->next;
stmt_close((MYSQL_STMT *)element->data, 0); stmt_close((MYSQL_STMT *)element->data, 0, 1);
} }
mysql->stmts= 0; mysql->stmts= 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment