andrey Thu, 29 Apr 2010 13:13:41 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=298771
Log: Fix possible crashes in case of OOM, as well as a leak. Changed paths: U php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c U php/php-src/trunk/ext/mysqlnd/mysqlnd.c Modified: php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c =================================================================== --- php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c 2010-04-29 12:48:06 UTC (rev 298770) +++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c 2010-04-29 13:13:41 UTC (rev 298771) @@ -780,8 +780,10 @@ DBG_INF_FMT("host=%s user=%s db=%s port=%d flags=%d", host?host:"", user?user:"", db?db:"", port, mysql_flags); if (!conn) { - conn = mysqlnd_init(FALSE); self_alloced = TRUE; + if (!(conn = mysqlnd_init(FALSE))) { + DBG_RETURN(NULL); + } } ret = conn->m->connect(conn, host, user, passwd, passwd_len, db, db_len, port, socket, mysql_flags TSRMLS_CC); @@ -1094,8 +1096,10 @@ MyISAM goes to 2500 BIT columns, double it for safety. */ result = mysqlnd_result_init(5000, conn->persistent TSRMLS_CC); + if (!result) { + DBG_RETURN(NULL); + } - if (FAIL == result->m.read_result_metadata(result, conn TSRMLS_CC)) { DBG_ERR("Error ocurred while reading metadata"); result->m.free_result(result, TRUE TSRMLS_CC); @@ -1105,6 +1109,11 @@ result->type = MYSQLND_RES_NORMAL; result->m.fetch_row = result->m.fetch_row_normal_unbuffered; result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED)); + if (!result->unbuf) { + DBG_ERR("OOM"); + result->m.free_result(result, TRUE TSRMLS_CC); + DBG_RETURN(NULL); + } result->unbuf->eof_reached = TRUE; DBG_RETURN(result); @@ -1933,7 +1942,13 @@ /* 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) { + DBG_RETURN(FAIL); + } conn->options.init_commands[conn->options.num_commands] = mnd_pestrdup(value, conn->persistent); + if (!conn->options.init_commands[conn->options.num_commands]) { + DBG_RETURN(FAIL); + } ++conn->options.num_commands; break; case MYSQL_READ_DEFAULT_FILE: @@ -1946,6 +1961,10 @@ break; case MYSQL_SET_CHARSET_NAME: DBG_INF("MYSQL_SET_CHARSET_NAME"); + 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); DBG_INF_FMT("charset=%s", conn->options.charset_name); break; Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd.c =================================================================== --- php/php-src/trunk/ext/mysqlnd/mysqlnd.c 2010-04-29 12:48:06 UTC (rev 298770) +++ php/php-src/trunk/ext/mysqlnd/mysqlnd.c 2010-04-29 13:13:41 UTC (rev 298771) @@ -780,8 +780,10 @@ DBG_INF_FMT("host=%s user=%s db=%s port=%d flags=%d", host?host:"", user?user:"", db?db:"", port, mysql_flags); if (!conn) { - conn = mysqlnd_init(FALSE); self_alloced = TRUE; + if (!(conn = mysqlnd_init(FALSE))) { + DBG_RETURN(NULL); + } } ret = conn->m->connect(conn, host, user, passwd, passwd_len, db, db_len, port, socket, mysql_flags TSRMLS_CC); @@ -1094,8 +1096,10 @@ MyISAM goes to 2500 BIT columns, double it for safety. */ result = mysqlnd_result_init(5000, conn->persistent TSRMLS_CC); + if (!result) { + DBG_RETURN(NULL); + } - if (FAIL == result->m.read_result_metadata(result, conn TSRMLS_CC)) { DBG_ERR("Error ocurred while reading metadata"); result->m.free_result(result, TRUE TSRMLS_CC); @@ -1105,6 +1109,11 @@ result->type = MYSQLND_RES_NORMAL; result->m.fetch_row = result->m.fetch_row_normal_unbuffered; result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED)); + if (!result->unbuf) { + DBG_ERR("OOM"); + result->m.free_result(result, TRUE TSRMLS_CC); + DBG_RETURN(NULL); + } result->unbuf->eof_reached = TRUE; DBG_RETURN(result); @@ -1933,7 +1942,13 @@ /* 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) { + DBG_RETURN(FAIL); + } conn->options.init_commands[conn->options.num_commands] = mnd_pestrdup(value, conn->persistent); + if (!conn->options.init_commands[conn->options.num_commands]) { + DBG_RETURN(FAIL); + } ++conn->options.num_commands; break; case MYSQL_READ_DEFAULT_FILE: @@ -1946,6 +1961,10 @@ break; case MYSQL_SET_CHARSET_NAME: DBG_INF("MYSQL_SET_CHARSET_NAME"); + 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); DBG_INF_FMT("charset=%s", conn->options.charset_name); break;
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php