Better handing of OOM in mysqlnd::set_client_option

This commit is contained in:
Andrey Hristov 2010-05-03 13:45:58 +00:00
parent 5c628d550b
commit 333581fcb4

View File

@ -1122,6 +1122,7 @@ MYSQLND_METHOD(mysqlnd_conn, list_fields)(MYSQLND * conn, const char *table, con
FALSE, TRUE TSRMLS_CC)) { FALSE, TRUE TSRMLS_CC)) {
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
/* /*
Prepare for the worst case. Prepare for the worst case.
MyISAM goes to 2500 BIT columns, double it for safety. MyISAM goes to 2500 BIT columns, double it for safety.
@ -1981,20 +1982,26 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
} }
break; break;
case MYSQL_INIT_COMMAND: case MYSQL_INIT_COMMAND:
{
char ** new_init_commands;
char * new_command;
DBG_INF("MYSQL_INIT_COMMAND"); DBG_INF("MYSQL_INIT_COMMAND");
DBG_INF_FMT("command=%s", value); DBG_INF_FMT("command=%s", value);
/* when num_commands is 0, then realloc will be effectively a malloc call, internally */ /* when num_commands is 0, then realloc will be effectively a malloc call, internally */
conn->options.init_commands = mnd_perealloc(conn->options.init_commands, sizeof(char *) * (conn->options.num_commands + 1), /* Don't assign to conn->options.init_commands because in case of OOM we will lose the pointer and leak */
conn->persistent); new_init_commands = mnd_perealloc(conn->options.init_commands, sizeof(char *) * (conn->options.num_commands + 1), conn->persistent);
if (!conn->options.init_commands) { if (!new_init_commands) {
goto oom; goto oom;
} }
conn->options.init_commands[conn->options.num_commands] = mnd_pestrdup(value, conn->persistent); conn->options.init_commands = new_init_commands;
if (!conn->options.init_commands[conn->options.num_commands]) { new_command = mnd_pestrdup(value, conn->persistent);
if (!new_command) {
goto oom; goto oom;
} }
conn->options.init_commands[conn->options.num_commands] = new_command;
++conn->options.num_commands; ++conn->options.num_commands;
break; break;
}
case MYSQL_READ_DEFAULT_FILE: case MYSQL_READ_DEFAULT_FILE:
case MYSQL_READ_DEFAULT_GROUP: case MYSQL_READ_DEFAULT_GROUP:
#ifdef WHEN_SUPPORTED_BY_MYSQLI #ifdef WHEN_SUPPORTED_BY_MYSQLI
@ -2004,17 +2011,19 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
/* currently not supported. Todo!! */ /* currently not supported. Todo!! */
break; break;
case MYSQL_SET_CHARSET_NAME: case MYSQL_SET_CHARSET_NAME:
{
char * new_charset_name = mnd_pestrdup(value, conn->persistent);
DBG_INF("MYSQL_SET_CHARSET_NAME"); DBG_INF("MYSQL_SET_CHARSET_NAME");
if (conn->options.charset_name) { if (!new_charset_name) {
mnd_pefree(conn->options.charset_name, conn->persistent);
conn->options.charset_name = NULL;
}
conn->options.charset_name = mnd_pestrdup(value, conn->persistent);
if (!conn->options.charset_name) {
goto oom; goto oom;
} }
if (conn->options.charset_name) {
mnd_pefree(conn->options.charset_name, conn->persistent);
}
conn->options.charset_name = new_charset_name;
DBG_INF_FMT("charset=%s", conn->options.charset_name); DBG_INF_FMT("charset=%s", conn->options.charset_name);
break; break;
}
#ifdef WHEN_SUPPORTED_BY_MYSQLI #ifdef WHEN_SUPPORTED_BY_MYSQLI
case MYSQL_SET_CHARSET_DIR: case MYSQL_SET_CHARSET_DIR:
case MYSQL_OPT_RECONNECT: case MYSQL_OPT_RECONNECT: