summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysqltest.cc2
-rw-r--r--include/sql_common.h7
-rw-r--r--libmysql/libmysql.c8
-rw-r--r--sql-common/client.c15
-rw-r--r--sql/protocol.cc4
5 files changed, 25 insertions, 11 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 6bd1472f6a3..b1784fdc7b6 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -7303,6 +7303,8 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
*/
if ((counter==0) && do_read_query_result(cn))
{
+ /* we've failed to collect the result set */
+ cn->pending= TRUE;
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
diff --git a/include/sql_common.h b/include/sql_common.h
index c27767bd0eb..307b443d6d6 100644
--- a/include/sql_common.h
+++ b/include/sql_common.h
@@ -1,7 +1,7 @@
#ifndef SQL_COMMON_INCLUDED
#define SQL_COMMON_INCLUDED
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -72,8 +72,9 @@ typedef struct st_mysql_methods
0, arg, length, 1, stmt)
extern CHARSET_INFO *default_client_charset_info;
-MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
- my_bool default_value, uint server_capabilities);
+MYSQL_FIELD *unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,
+ uint fields, my_bool default_value,
+ uint server_capabilities);
void free_rows(MYSQL_DATA *cur);
void free_old_query(MYSQL *mysql);
void end_server(MYSQL *mysql);
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 9f5e6cc5f1a..bb814dade09 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -802,7 +802,7 @@ MYSQL_FIELD *cli_list_fields(MYSQL *mysql)
return NULL;
mysql->field_count= (uint) query->rows;
- return unpack_fields(query,&mysql->field_alloc,
+ return unpack_fields(mysql, query,&mysql->field_alloc,
mysql->field_count, 1, mysql->server_capabilities);
}
@@ -862,7 +862,7 @@ mysql_list_processes(MYSQL *mysql)
if (!(fields = (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*) 0,
protocol_41(mysql) ? 7 : 5)))
DBUG_RETURN(NULL);
- if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0,
+ if (!(mysql->fields=unpack_fields(mysql, fields,&mysql->field_alloc,field_count,0,
mysql->server_capabilities)))
DBUG_RETURN(0);
mysql->status=MYSQL_STATUS_GET_RESULT;
@@ -1434,7 +1434,7 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
if (!(fields_data= (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0,7)))
DBUG_RETURN(1);
- if (!(stmt->fields= unpack_fields(fields_data,&stmt->mem_root,
+ if (!(stmt->fields= unpack_fields(mysql, fields_data,&stmt->mem_root,
field_count,0,
mysql->server_capabilities)))
DBUG_RETURN(1);
diff --git a/sql-common/client.c b/sql-common/client.c
index a453a1a161f..08f4bfb1151 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1430,7 +1430,7 @@ static void cli_fetch_lengths(ulong *to, MYSQL_ROW column,
***************************************************************************/
MYSQL_FIELD *
-unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
+unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
my_bool default_value, uint server_capabilities)
{
MYSQL_ROWS *row;
@@ -1443,6 +1443,7 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
if (!result)
{
free_rows(data); /* Free old data */
+ set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(0);
}
bzero((char*) field, (uint) sizeof(MYSQL_FIELD)*fields);
@@ -1470,6 +1471,14 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
field->org_name_length= lengths[5];
/* Unpack fixed length parts */
+ if (lengths[6] != 12)
+ {
+ /* malformed packet. signal an error. */
+ free_rows(data); /* Free old data */
+ set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
+ DBUG_RETURN(0);
+ }
+
pos= (uchar*) row->data[6];
field->charsetnr= uint2korr(pos);
field->length= (uint) uint4korr(pos+2);
@@ -3815,7 +3824,7 @@ get_info:
if (!(fields=cli_read_rows(mysql,(MYSQL_FIELD*)0, protocol_41(mysql) ? 7:5)))
DBUG_RETURN(1);
- if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
+ if (!(mysql->fields=unpack_fields(mysql, fields,&mysql->field_alloc,
(uint) field_count,0,
mysql->server_capabilities)))
DBUG_RETURN(1);
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 53ab032517e..5c1533ad10d 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -722,6 +722,8 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
/* Store fixed length fields */
pos= (char*) local_packet->ptr()+local_packet->length();
*pos++= 12; // Length of packed fields
+ /* inject a NULL to test the client */
+ DBUG_EXECUTE_IF("poison_rs_fields", pos[-1]= 0xfb;);
if (item->charset_for_protocol() == &my_charset_bin || thd_charset == NULL)
{
/* No conversion */