List:Commits« Previous MessageNext Message »
From:kgeorge Date:November 13 2006 10:29am
Subject:bk commit into 4.1 tree (gkodinov:1.2536) BUG#19216
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of kgeorge. When kgeorge does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-11-13 12:28:55+02:00, gkodinov@stripped +4 -0
  Bug #19216: Client crashes on long SELECT
   The server sends a number of columns to the client.
   It uses a limited "fast" function for that instead of the
   general one. This fast function cannot send numbers larger 
   than 2 bytes. 
   This causes the client to expect smaller number of columns. 
   The client writes outside of the allocated memory buffer 
   as a result.
   Fixed the server to use the general function to send column
   count.
   Fixed the client to check the column count before writing
   column data. 

  mysql-test/t/mysql_client.test@stripped, 2006-11-13 12:28:49+02:00, gkodinov@stripped +18 -0
    Bug #19216: Client crashes on long SELECT
     - test case

  sql-common/client.c@stripped, 2006-11-13 12:28:51+02:00, gkodinov@stripped +2 -0
    Bug #19216: Client crashes on long SELECT
     - fixed the client to check for older servers (without the fix).

  sql/protocol.cc@stripped, 2006-11-13 12:28:50+02:00, gkodinov@stripped +9 -9
    Bug #19216: Client crashes on long SELECT
     - renamed the function for bether comprehention
       and made it local
     - used the right (non-local) function to transfer 
       the column count in Protocol::send_fields

  sql/protocol.h@stripped, 2006-11-13 12:28:50+02:00, gkodinov@stripped +0 -1
    Bug #19216: Client crashes on long SELECT
     - made optimized net_store_length local

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	gkodinov
# Host:	macbook.gmz
# Root:	/Users/kgeorge/mysql/work/B19216-4.1-opt

--- 1.105/sql/protocol.cc	2006-01-18 21:50:26 +02:00
+++ 1.106/sql/protocol.cc	2006-11-13 12:28:50 +02:00
@@ -43,7 +43,7 @@ bool Protocol_prep::net_store_data(const
       packet->realloc(packet_length+9+length))
     return 1;
   char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
-				    (ulonglong) length);
+				    length);
   memcpy(to,from,length);
   packet->length((uint) (to+length-packet->ptr()));
   return 0;
@@ -297,8 +297,8 @@ send_ok(THD *thd, ha_rows affected_rows,
     DBUG_VOID_RETURN;
 
   buff[0]=0;					// No fields
-  pos=net_store_length(buff+1,(ulonglong) affected_rows);
-  pos=net_store_length(pos, (ulonglong) id);
+  pos=net_store_length(buff+1,affected_rows);
+  pos=net_store_length(pos, id);
   if (thd->client_capabilities & CLIENT_PROTOCOL_41)
   {
     DBUG_PRINT("info",
@@ -416,7 +416,7 @@ bool send_old_password_request(THD *thd)
   ulonglong for bigger numbers.
 */
 
-char *net_store_length(char *pkg, uint length)
+static char *net_store_length_fast(char *pkg, uint length)
 {
   uchar *packet=(uchar*) pkg;
   if (length < 251)
@@ -439,7 +439,7 @@ char *net_store_length(char *pkg, uint l
 
 char *net_store_data(char *to,const char *from, uint length)
 {
-  to=net_store_length(to,length);
+  to=net_store_length_fast(to,length);
   memcpy(to,from,length);
   return to+length;
 }
@@ -448,7 +448,7 @@ char *net_store_data(char *to,int32 from
 {
   char buff[20];
   uint length=(uint) (int10_to_str(from,buff,10)-buff);
-  to=net_store_length(to,length);
+  to=net_store_length_fast(to,length);
   memcpy(to,buff,length);
   return to+length;
 }
@@ -457,7 +457,7 @@ char *net_store_data(char *to,longlong f
 {
   char buff[22];
   uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
-  to=net_store_length(to,length);
+  to=net_store_length_fast(to,length);
   memcpy(to,buff,length);
   return to+length;
 }
@@ -520,7 +520,7 @@ bool Protocol::send_fields(List<Item> *l
 
   if (flag & 1)
   {				// Packet with number of elements
-    char *pos=net_store_length(buff, (uint) list->elements);
+    char *pos=net_store_length(buff, list->elements);
     (void) my_net_write(&thd->net, buff,(uint) (pos-buff));
   }
 
@@ -648,7 +648,7 @@ bool Protocol::send_records_num(List<Ite
 {
   char *pos;
   char buff[20];
-  pos=net_store_length(buff, (uint) list->elements);
+  pos=net_store_length(buff, list->elements);
   pos=net_store_length(pos, records);
   return my_net_write(&thd->net, buff,(uint) (pos-buff));
 }

--- 1.93/sql-common/client.c	2006-09-27 15:49:13 +03:00
+++ 1.94/sql-common/client.c	2006-11-13 12:28:51 +02:00
@@ -1173,6 +1173,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT 
     for (row=data->data; row ; row = row->next,field++)
     {
       uchar *pos;
+      /* fields count may be wrong */
+      DBUG_ASSERT ((field - result) < fields);
       cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
       field->catalog  = strdup_root(alloc,(char*) row->data[0]);
       field->db       = strdup_root(alloc,(char*) row->data[1]);

--- 1.22/sql/protocol.h	2005-05-04 16:05:53 +03:00
+++ 1.23/sql/protocol.h	2006-11-13 12:28:50 +02:00
@@ -177,7 +177,6 @@ void send_ok(THD *thd, ha_rows affected_
 	     const char *info=0);
 void send_eof(THD *thd, bool no_flush=0);
 bool send_old_password_request(THD *thd);
-char *net_store_length(char *packet,uint length);
 char *net_store_data(char *to,const char *from, uint length);
 char *net_store_data(char *to,int32 from);
 char *net_store_data(char *to,longlong from);

--- 1.3/mysql-test/t/mysql_client.test	2006-08-16 20:55:15 +03:00
+++ 1.4/mysql-test/t/mysql_client.test	2006-11-13 12:28:49 +02:00
@@ -33,3 +33,21 @@
 #
 --exec echo 'help' | $MYSQL   >  $MYSQLTEST_VARDIR/tmp/bug20328.tmp
 --exec echo 'help ' | $MYSQL  >  $MYSQLTEST_VARDIR/tmp/bug20328.tmp
+
+#
+# Bug #19216: Client crashes on long SELECT
+#
+--exec echo "select" > $MYSQLTEST_VARDIR/tmp/b19216.tmp
+# 3400 * 20 makes 68000 columns that is more than the max number that can fit 
+# in a 16 bit number.
+let $i= 3400;
+while ($i)
+{
+  --exec echo "'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a'," >> $MYSQLTEST_VARDIR/tmp/b19216.tmp
+  dec $i;
+}
+
+--exec echo "'b';" >> $MYSQLTEST_VARDIR/tmp/b19216.tmp
+--disable_query_log
+--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/b19216.tmp >/dev/null
+--enable_query_log
Thread
bk commit into 4.1 tree (gkodinov:1.2536) BUG#19216kgeorge13 Nov