summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysqltest.cc4
-rw-r--r--include/sql_common.h8
-rw-r--r--libmysql/libmysql.c8
-rw-r--r--sql-common/client.c15
-rw-r--r--sql/protocol.cc4
5 files changed, 27 insertions, 12 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 593bb8ea290..e595493ccf0 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1,5 +1,5 @@
/*
- 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
@@ -6848,6 +6848,8 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
*/
if ((counter==0) && mysql_read_query_result(mysql))
{
+ /* 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 9e43d076ba9..b64277ce7e1 100644
--- a/include/sql_common.h
+++ b/include/sql_common.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2003-2004, 2006 MySQL AB
+/*
+ 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
@@ -23,8 +24,9 @@ extern "C" {
#endif
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 562da594fea..5d153317150 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, 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
@@ -1254,7 +1254,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);
}
@@ -1314,7 +1314,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;
@@ -1891,7 +1891,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 0df7c242969..51911d913c7 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1,5 +1,5 @@
/*
- 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
@@ -1268,7 +1268,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;
@@ -1281,6 +1281,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);
@@ -1308,6 +1309,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);
@@ -2868,7 +2877,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 5a727d94c46..a74f6084df4 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
@@ -620,6 +620,8 @@ bool Protocol::send_fields(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->collation.collation == &my_charset_bin || thd_charset == NULL)
{
/* No conversion */