diff options
-rw-r--r-- | client/mysqltest.cc | 2 | ||||
-rw-r--r-- | include/sql_common.h | 7 | ||||
-rw-r--r-- | libmysql/libmysql.c | 8 | ||||
-rw-r--r-- | sql-common/client.c | 15 | ||||
-rw-r--r-- | sql/protocol.cc | 4 |
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 */ |