Commit fca90750 authored by unknown's avatar unknown
Browse files

A fix and test case for Bug#8330 "mysql_stmt_execute crashes" (libmysql).


libmysql/libmysql.c:
  Fix for bug#8330 "mysql_stmt_execute crashes": we need to bail out
  from mysql_stmt_execute if mysql->net is occupied with a result set of
  another statement. Otherwise on the next attempt to use net we get
  a crash, as it's freed in case of error.
tests/mysql_client_test.c:
  A test case for Bug#8330 "mysql_stmt_execute craches" (libmysql)
parent 425f2f91
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -2467,6 +2467,11 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
      set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate);
      DBUG_RETURN(1);
    }
    if (stmt->mysql->status != MYSQL_STATUS_READY)
    {
      set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
      DBUG_RETURN(1);
    }

    net_clear(net);				/* Sets net->write_pos */
    /* Reserve place for null-marker bytes */
+54 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <my_global.h>
#include <my_sys.h>
#include <mysql.h>
#include <errmsg.h>
#include <my_getopt.h>
#include <m_string.h>

@@ -11532,6 +11533,58 @@ static void test_bug6761(void)
  myquery(rc);
}


/* Bug#8330 - Bug #8330   mysql_stmt_execute crashes (libmysql) */

static void test_bug8330()
{
  const char *stmt_text;
  MYSQL_STMT *stmt[2];
  int i, rc;
  char *query= "select a,b from t1 where a=?";
  MYSQL_BIND bind[2];
  long lval[2];

  myheader("test_bug8330");

  stmt_text= "drop table if exists t1";
  /* in case some previos test failed */
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);
  stmt_text= "create table t1 (a int, b int)";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);

  bzero(bind, sizeof(bind));
  for (i=0; i < 2; i++)
  {
    stmt[i]= mysql_stmt_init(mysql);
    rc= mysql_stmt_prepare(stmt[i], query, strlen(query));
    check_execute(stmt[i], rc);

    bind[i].buffer_type= MYSQL_TYPE_LONG;
    bind[i].buffer= (void*) &lval[i];
    bind[i].is_null= 0;
    mysql_stmt_bind_param(stmt[i], &bind[i]);
  }

  rc= mysql_stmt_execute(stmt[0]);
  check_execute(stmt[0], rc);

  rc= mysql_stmt_execute(stmt[1]);
  DIE_UNLESS(rc && mysql_stmt_errno(stmt[1]) == CR_COMMANDS_OUT_OF_SYNC);
  rc= mysql_stmt_execute(stmt[0]);
  check_execute(stmt[0], rc);

  mysql_stmt_close(stmt[0]);
  mysql_stmt_close(stmt[1]);

  stmt_text= "drop table t1";
  rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
  myquery(rc);
}


/*
  Read and parse arguments and MySQL options from my.cnf
*/
@@ -11739,6 +11792,7 @@ static struct my_tests_st my_tests[]= {
  { "test_conversion", test_conversion },
  { "test_rewind", test_rewind },
  { "test_bug6761", test_bug6761 },
  { "test_bug8330", test_bug8330 },
  { 0, 0 }
};