andrey Mon, 03 May 2010 18:50:47 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=298920
Log:
Handle OOM stemming from mysqlnd_result_init in the same
function and up the stack.
Changed paths:
U php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c
U php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c
U php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c
U php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c
Modified: php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c 2010-05-03 17:47:58 UTC (rev 298919)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c 2010-05-03 18:50:47 UTC (rev 298920)
@@ -156,20 +156,35 @@
SET_EMPTY_ERROR(stmt->conn->error_info);
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS);
- result = mysqlnd_result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC);
+ do {
+ result = mysqlnd_result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC);
+ if (!result) {
+ SET_OOM_ERROR(stmt->conn->error_info);
+ break;
+ }
- result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+ result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+ if (!result->meta) {
+ SET_OOM_ERROR(stmt->conn->error_info);
+ break;
+ }
- if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
- stmt->upsert_status.affected_rows = result->stored_data->row_count;
- stmt->state = MYSQLND_STMT_PREPARED;
- result->type = MYSQLND_RES_PS_BUF;
- } else {
- stmt->error_info = conn->error_info;
- stmt->state = MYSQLND_STMT_PREPARED;
+ if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
+ stmt->upsert_status.affected_rows = result->stored_data->row_count;
+ stmt->state = MYSQLND_STMT_PREPARED;
+ result->type = MYSQLND_RES_PS_BUF;
+ } else {
+ stmt->error_info = conn->error_info;
+ stmt->state = MYSQLND_STMT_PREPARED;
+ break;
+ }
+ DBG_RETURN(result);
+ } while (0);
+
+ if (result) {
+ result->m.free_result(result, TRUE TSRMLS_CC);
}
-
- DBG_RETURN(result);
+ DBG_RETURN(NULL);
}
/* }}} */
@@ -366,6 +381,10 @@
*/
if (stmt_to_prepare->field_count) {
MYSQLND_RES * result = mysqlnd_result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent TSRMLS_CC);
+ if (!result) {
+ SET_OOM_ERROR(stmt->conn->error_info);
+ goto fail;
+ }
/* Allocate the result now as it is needed for the reading of metadata */
stmt_to_prepare->result = result;
@@ -374,7 +393,8 @@
result->type = MYSQLND_RES_PS_BUF;
if (FAIL == result->m.read_result_metadata(result, stmt_to_prepare->conn TSRMLS_CC) ||
- FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare TSRMLS_CC)) {
+ FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare TSRMLS_CC))
+ {
goto fail;
}
}
@@ -1655,15 +1675,32 @@
In the meantime we don't need a zval cache reference for this fake
result set, so we don't get one.
*/
- result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
- result->type = MYSQLND_RES_NORMAL;
- result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
- result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
- result->unbuf->eof_reached = TRUE;
- result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+ do {
+ result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
+ if (!result) {
+ break;
+ }
+ 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) {
+ break;
+ }
+ result->unbuf->eof_reached = TRUE;
+ result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+ if (!result->meta) {
+ break;
+ }
- DBG_INF_FMT("result=%p", result);
- DBG_RETURN(result);
+ DBG_INF_FMT("result=%p", result);
+ DBG_RETURN(result);
+ } while (0);
+
+ SET_OOM_ERROR(stmt->conn->error_info);
+ if (result) {
+ result->m.free_result(result, TRUE TSRMLS_CC);
+ }
+ DBG_RETURN(NULL);
}
/* }}} */
Modified: php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c 2010-05-03 17:47:58 UTC (rev 298919)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c 2010-05-03 18:50:47 UTC (rev 298920)
@@ -353,6 +353,7 @@
MYSQLND_STMT_DATA * stmt = s ? s->data:NULL;
enum_func_status ret;
MYSQLND_PACKET_RSET_HEADER * rset_header;
+ MYSQLND_PACKET_EOF * fields_eof;
DBG_ENTER("mysqlnd_query_read_result_set_header");
DBG_INF_FMT("stmt=%d", stmt? stmt->stmt_id:0);
@@ -420,8 +421,7 @@
ret = PASS;
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_NON_RSET_QUERY);
break;
- default:{ /* Result set */
- MYSQLND_PACKET_EOF * fields_eof;
+ default: do { /* Result set */
MYSQLND_RES * result;
enum_mysqlnd_collected_stats stat = STAT_LAST;
@@ -464,7 +464,12 @@
}
result = stmt->result;
}
-
+ if (!result) {
+ SET_OOM_ERROR(conn->error_info);
+ ret = FAIL;
+ break;
+ }
+
if (FAIL == (ret = result->m.read_result_metadata(result, conn TSRMLS_CC))) {
/* For PS, we leave them in Prepared state */
if (!stmt && conn->current_result) {
@@ -517,11 +522,9 @@
}
MYSQLND_INC_CONN_STATISTIC(conn->stats, stat);
}
-
- PACKET_FREE(fields_eof);
-
- break;
- }
+ } while (0);
+ PACKET_FREE(fields_eof);
+ break; /* switch break */
}
} while (0);
PACKET_FREE(rset_header);
@@ -1546,6 +1549,10 @@
DBG_ENTER("mysqlnd_result_init");
DBG_INF_FMT("field_count=%u", field_count);
+
+ if (!ret) {
+ DBG_RETURN(NULL);
+ }
ret->persistent = persistent;
ret->field_count = field_count;
Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c 2010-05-03 17:47:58 UTC (rev 298919)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c 2010-05-03 18:50:47 UTC (rev 298920)
@@ -156,20 +156,35 @@
SET_EMPTY_ERROR(stmt->conn->error_info);
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS);
- result = mysqlnd_result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC);
+ do {
+ result = mysqlnd_result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC);
+ if (!result) {
+ SET_OOM_ERROR(stmt->conn->error_info);
+ break;
+ }
- result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+ result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+ if (!result->meta) {
+ SET_OOM_ERROR(stmt->conn->error_info);
+ break;
+ }
- if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
- stmt->upsert_status.affected_rows = result->stored_data->row_count;
- stmt->state = MYSQLND_STMT_PREPARED;
- result->type = MYSQLND_RES_PS_BUF;
- } else {
- stmt->error_info = conn->error_info;
- stmt->state = MYSQLND_STMT_PREPARED;
+ if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
+ stmt->upsert_status.affected_rows = result->stored_data->row_count;
+ stmt->state = MYSQLND_STMT_PREPARED;
+ result->type = MYSQLND_RES_PS_BUF;
+ } else {
+ stmt->error_info = conn->error_info;
+ stmt->state = MYSQLND_STMT_PREPARED;
+ break;
+ }
+ DBG_RETURN(result);
+ } while (0);
+
+ if (result) {
+ result->m.free_result(result, TRUE TSRMLS_CC);
}
-
- DBG_RETURN(result);
+ DBG_RETURN(NULL);
}
/* }}} */
@@ -366,6 +381,10 @@
*/
if (stmt_to_prepare->field_count) {
MYSQLND_RES * result = mysqlnd_result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent TSRMLS_CC);
+ if (!result) {
+ SET_OOM_ERROR(stmt->conn->error_info);
+ goto fail;
+ }
/* Allocate the result now as it is needed for the reading of metadata */
stmt_to_prepare->result = result;
@@ -374,7 +393,8 @@
result->type = MYSQLND_RES_PS_BUF;
if (FAIL == result->m.read_result_metadata(result, stmt_to_prepare->conn TSRMLS_CC) ||
- FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare TSRMLS_CC)) {
+ FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare TSRMLS_CC))
+ {
goto fail;
}
}
@@ -1655,15 +1675,32 @@
In the meantime we don't need a zval cache reference for this fake
result set, so we don't get one.
*/
- result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
- result->type = MYSQLND_RES_NORMAL;
- result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
- result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
- result->unbuf->eof_reached = TRUE;
- result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+ do {
+ result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
+ if (!result) {
+ break;
+ }
+ 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) {
+ break;
+ }
+ result->unbuf->eof_reached = TRUE;
+ result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+ if (!result->meta) {
+ break;
+ }
- DBG_INF_FMT("result=%p", result);
- DBG_RETURN(result);
+ DBG_INF_FMT("result=%p", result);
+ DBG_RETURN(result);
+ } while (0);
+
+ SET_OOM_ERROR(stmt->conn->error_info);
+ if (result) {
+ result->m.free_result(result, TRUE TSRMLS_CC);
+ }
+ DBG_RETURN(NULL);
}
/* }}} */
Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c 2010-05-03 17:47:58 UTC (rev 298919)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c 2010-05-03 18:50:47 UTC (rev 298920)
@@ -353,6 +353,7 @@
MYSQLND_STMT_DATA * stmt = s ? s->data:NULL;
enum_func_status ret;
MYSQLND_PACKET_RSET_HEADER * rset_header;
+ MYSQLND_PACKET_EOF * fields_eof;
DBG_ENTER("mysqlnd_query_read_result_set_header");
DBG_INF_FMT("stmt=%d", stmt? stmt->stmt_id:0);
@@ -420,8 +421,7 @@
ret = PASS;
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_NON_RSET_QUERY);
break;
- default:{ /* Result set */
- MYSQLND_PACKET_EOF * fields_eof;
+ default: do { /* Result set */
MYSQLND_RES * result;
enum_mysqlnd_collected_stats stat = STAT_LAST;
@@ -464,7 +464,12 @@
}
result = stmt->result;
}
-
+ if (!result) {
+ SET_OOM_ERROR(conn->error_info);
+ ret = FAIL;
+ break;
+ }
+
if (FAIL == (ret = result->m.read_result_metadata(result, conn TSRMLS_CC))) {
/* For PS, we leave them in Prepared state */
if (!stmt && conn->current_result) {
@@ -517,11 +522,9 @@
}
MYSQLND_INC_CONN_STATISTIC(conn->stats, stat);
}
-
- PACKET_FREE(fields_eof);
-
- break;
- }
+ } while (0);
+ PACKET_FREE(fields_eof);
+ break; /* switch break */
}
} while (0);
PACKET_FREE(rset_header);
@@ -1546,6 +1549,10 @@
DBG_ENTER("mysqlnd_result_init");
DBG_INF_FMT("field_count=%u", field_count);
+
+ if (!ret) {
+ DBG_RETURN(NULL);
+ }
ret->persistent = persistent;
ret->field_count = field_count;
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php