diff options
author | Andrey Hristov <andrey@php.net> | 2010-05-03 13:45:58 +0000 |
---|---|---|
committer | Andrey Hristov <andrey@php.net> | 2010-05-03 13:45:58 +0000 |
commit | d0abd9510e98252c268033dcdd1d4dacd859472b (patch) | |
tree | d274dda0cae519736da6002db3611e3a50d79d96 /ext/mysqlnd/mysqlnd.c | |
parent | 0871df60a3ddcbeeb07b13cf733cb1344cf19427 (diff) | |
download | php-git-d0abd9510e98252c268033dcdd1d4dacd859472b.tar.gz |
Better handing of OOM in mysqlnd::set_client_option
Diffstat (limited to 'ext/mysqlnd/mysqlnd.c')
-rw-r--r-- | ext/mysqlnd/mysqlnd.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index 4bb6c5c166..414d6f2b5a 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -1122,6 +1122,7 @@ MYSQLND_METHOD(mysqlnd_conn, list_fields)(MYSQLND * conn, const char *table, con FALSE, TRUE TSRMLS_CC)) { DBG_RETURN(NULL); } + /* Prepare for the worst case. 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; case MYSQL_INIT_COMMAND: + { + char ** new_init_commands; + char * new_command; DBG_INF("MYSQL_INIT_COMMAND"); DBG_INF_FMT("command=%s", value); /* 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), - conn->persistent); - if (!conn->options.init_commands) { + /* Don't assign to conn->options.init_commands because in case of OOM we will lose the pointer and leak */ + new_init_commands = mnd_perealloc(conn->options.init_commands, sizeof(char *) * (conn->options.num_commands + 1), conn->persistent); + if (!new_init_commands) { goto oom; } - conn->options.init_commands[conn->options.num_commands] = mnd_pestrdup(value, conn->persistent); - if (!conn->options.init_commands[conn->options.num_commands]) { + conn->options.init_commands = new_init_commands; + new_command = mnd_pestrdup(value, conn->persistent); + if (!new_command) { goto oom; } + conn->options.init_commands[conn->options.num_commands] = new_command; ++conn->options.num_commands; break; + } case MYSQL_READ_DEFAULT_FILE: case MYSQL_READ_DEFAULT_GROUP: #ifdef WHEN_SUPPORTED_BY_MYSQLI @@ -2004,17 +2011,19 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn, /* currently not supported. Todo!! */ break; case MYSQL_SET_CHARSET_NAME: + { + char * new_charset_name = mnd_pestrdup(value, conn->persistent); DBG_INF("MYSQL_SET_CHARSET_NAME"); + if (!new_charset_name) { + goto oom; + } if (conn->options.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; } + conn->options.charset_name = new_charset_name; DBG_INF_FMT("charset=%s", conn->options.charset_name); break; + } #ifdef WHEN_SUPPORTED_BY_MYSQLI case MYSQL_SET_CHARSET_DIR: case MYSQL_OPT_RECONNECT: |