mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Handle OOM stemming from mysqlnd_result_init in the same
function and up the stack.
This commit is contained in:
parent
d90f8560aa
commit
2b18a3ff93
2 changed files with 72 additions and 28 deletions
|
@ -156,20 +156,35 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s TSRMLS_DC)
|
||||||
SET_EMPTY_ERROR(stmt->conn->error_info);
|
SET_EMPTY_ERROR(stmt->conn->error_info);
|
||||||
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS);
|
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))) {
|
if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
|
||||||
stmt->upsert_status.affected_rows = result->stored_data->row_count;
|
stmt->upsert_status.affected_rows = result->stored_data->row_count;
|
||||||
stmt->state = MYSQLND_STMT_PREPARED;
|
stmt->state = MYSQLND_STMT_PREPARED;
|
||||||
result->type = MYSQLND_RES_PS_BUF;
|
result->type = MYSQLND_RES_PS_BUF;
|
||||||
} else {
|
} else {
|
||||||
stmt->error_info = conn->error_info;
|
stmt->error_info = conn->error_info;
|
||||||
stmt->state = MYSQLND_STMT_PREPARED;
|
stmt->state = MYSQLND_STMT_PREPARED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBG_RETURN(result);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
result->m.free_result(result, TRUE TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
DBG_RETURN(NULL);
|
||||||
DBG_RETURN(result);
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -366,6 +381,10 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const
|
||||||
*/
|
*/
|
||||||
if (stmt_to_prepare->field_count) {
|
if (stmt_to_prepare->field_count) {
|
||||||
MYSQLND_RES * result = mysqlnd_result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent TSRMLS_CC);
|
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 */
|
/* Allocate the result now as it is needed for the reading of metadata */
|
||||||
stmt_to_prepare->result = result;
|
stmt_to_prepare->result = result;
|
||||||
|
|
||||||
|
@ -374,7 +393,8 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const
|
||||||
result->type = MYSQLND_RES_PS_BUF;
|
result->type = MYSQLND_RES_PS_BUF;
|
||||||
|
|
||||||
if (FAIL == result->m.read_result_metadata(result, stmt_to_prepare->conn TSRMLS_CC) ||
|
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1655,15 +1675,32 @@ MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const s TSRMLS_DC)
|
||||||
In the meantime we don't need a zval cache reference for this fake
|
In the meantime we don't need a zval cache reference for this fake
|
||||||
result set, so we don't get one.
|
result set, so we don't get one.
|
||||||
*/
|
*/
|
||||||
result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
|
do {
|
||||||
result->type = MYSQLND_RES_NORMAL;
|
result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
|
||||||
result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
|
if (!result) {
|
||||||
result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
|
break;
|
||||||
result->unbuf->eof_reached = TRUE;
|
}
|
||||||
result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE 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));
|
||||||
|
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_INF_FMT("result=%p", result);
|
||||||
DBG_RETURN(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);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -353,6 +353,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
|
||||||
MYSQLND_STMT_DATA * stmt = s ? s->data:NULL;
|
MYSQLND_STMT_DATA * stmt = s ? s->data:NULL;
|
||||||
enum_func_status ret;
|
enum_func_status ret;
|
||||||
MYSQLND_PACKET_RSET_HEADER * rset_header;
|
MYSQLND_PACKET_RSET_HEADER * rset_header;
|
||||||
|
MYSQLND_PACKET_EOF * fields_eof;
|
||||||
|
|
||||||
DBG_ENTER("mysqlnd_query_read_result_set_header");
|
DBG_ENTER("mysqlnd_query_read_result_set_header");
|
||||||
DBG_INF_FMT("stmt=%d", stmt? stmt->stmt_id:0);
|
DBG_INF_FMT("stmt=%d", stmt? stmt->stmt_id:0);
|
||||||
|
@ -420,8 +421,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
|
||||||
ret = PASS;
|
ret = PASS;
|
||||||
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_NON_RSET_QUERY);
|
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_NON_RSET_QUERY);
|
||||||
break;
|
break;
|
||||||
default:{ /* Result set */
|
default: do { /* Result set */
|
||||||
MYSQLND_PACKET_EOF * fields_eof;
|
|
||||||
MYSQLND_RES * result;
|
MYSQLND_RES * result;
|
||||||
enum_mysqlnd_collected_stats stat = STAT_LAST;
|
enum_mysqlnd_collected_stats stat = STAT_LAST;
|
||||||
|
|
||||||
|
@ -464,7 +464,12 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
|
||||||
}
|
}
|
||||||
result = stmt->result;
|
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))) {
|
if (FAIL == (ret = result->m.read_result_metadata(result, conn TSRMLS_CC))) {
|
||||||
/* For PS, we leave them in Prepared state */
|
/* For PS, we leave them in Prepared state */
|
||||||
if (!stmt && conn->current_result) {
|
if (!stmt && conn->current_result) {
|
||||||
|
@ -517,11 +522,9 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
|
||||||
}
|
}
|
||||||
MYSQLND_INC_CONN_STATISTIC(conn->stats, stat);
|
MYSQLND_INC_CONN_STATISTIC(conn->stats, stat);
|
||||||
}
|
}
|
||||||
|
} while (0);
|
||||||
PACKET_FREE(fields_eof);
|
PACKET_FREE(fields_eof);
|
||||||
|
break; /* switch break */
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
PACKET_FREE(rset_header);
|
PACKET_FREE(rset_header);
|
||||||
|
@ -1546,6 +1549,10 @@ mysqlnd_result_init(unsigned int field_count, zend_bool persistent TSRMLS_DC)
|
||||||
|
|
||||||
DBG_ENTER("mysqlnd_result_init");
|
DBG_ENTER("mysqlnd_result_init");
|
||||||
DBG_INF_FMT("field_count=%u", field_count);
|
DBG_INF_FMT("field_count=%u", field_count);
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
DBG_RETURN(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
ret->persistent = persistent;
|
ret->persistent = persistent;
|
||||||
ret->field_count = field_count;
|
ret->field_count = field_count;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue