Skip to content

Commit 8898c1e

Browse files
committed
MySQLnd: Fix potential leak when reading cursor
Perform the same checkpointing twe do in other row reading functions.
1 parent 1144b85 commit 8898c1e

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

ext/mysqlnd/mysqlnd_ps.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, zval **row_ptr, const unsign
754754
MYSQLND_CONN_DATA * conn = stmt->conn;
755755
zend_uchar buf[MYSQLND_STMT_ID_LENGTH /* statement id */ + 4 /* number of rows to fetch */];
756756
MYSQLND_PACKET_ROW * row_packet;
757+
void *checkpoint;
757758

758759
DBG_ENTER("mysqlnd_fetch_stmt_row_cursor");
759760

@@ -790,6 +791,9 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, zval **row_ptr, const unsign
790791

791792
}
792793

794+
checkpoint = result->memory_pool->checkpoint;
795+
mysqlnd_mempool_save_state(result->memory_pool);
796+
793797
UPSERT_STATUS_RESET(stmt->upsert_status);
794798
if (PASS == (ret = PACKET_READ(conn, row_packet)) && !row_packet->eof) {
795799
if (row_ptr) {
@@ -804,6 +808,8 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, zval **row_ptr, const unsign
804808
conn->options->int_and_float_native,
805809
conn->stats))
806810
{
811+
mysqlnd_mempool_restore_state(result->memory_pool);
812+
result->memory_pool->checkpoint = checkpoint;
807813
DBG_RETURN(FAIL);
808814
}
809815
} else {
@@ -812,11 +818,6 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, zval **row_ptr, const unsign
812818
}
813819
/* We asked for one row, the next one should be EOF, eat it */
814820
ret = PACKET_READ(conn, row_packet);
815-
if (row_packet->row_buffer.ptr) {
816-
row_packet->result_set_memory_pool->free_chunk(
817-
row_packet->result_set_memory_pool, row_packet->row_buffer.ptr);
818-
row_packet->row_buffer.ptr = NULL;
819-
}
820821
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_PS_CURSOR);
821822

822823
result->unbuf->row_count++;
@@ -837,12 +838,14 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, zval **row_ptr, const unsign
837838
UPSERT_STATUS_SET_SERVER_STATUS(stmt->upsert_status, row_packet->server_status);
838839
UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, row_packet->server_status);
839840

841+
mysqlnd_mempool_restore_state(result->memory_pool);
842+
result->memory_pool->checkpoint = checkpoint;
843+
840844
DBG_INF_FMT("ret=%s fetched=%u server_status=%u warnings=%u eof=%u",
841845
ret == PASS? "PASS":"FAIL", *fetched_anything,
842846
row_packet->server_status, row_packet->warning_count,
843847
result->unbuf->eof_reached);
844848
DBG_RETURN(ret);
845-
return FAIL;
846849
}
847850
/* }}} */
848851

0 commit comments

Comments
 (0)