Skip to content

Commit 72737b0

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fix #79038: PDOStatement::nextRowset() leaks column values
2 parents 4804dc2 + 3090c88 commit 72737b0

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

ext/pdo_odbc/odbc_stmt.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,14 @@ static void free_cols(pdo_stmt_t *stmt, pdo_odbc_stmt *S)
124124
if (S->cols) {
125125
int i;
126126

127-
for (i = 0; i < stmt->column_count; i++) {
127+
for (i = 0; i < S->col_count; i++) {
128128
if (S->cols[i].data) {
129129
efree(S->cols[i].data);
130130
}
131131
}
132132
efree(S->cols);
133133
S->cols = NULL;
134+
S->col_count = 0;
134135
}
135136
}
136137

@@ -260,14 +261,14 @@ static int odbc_stmt_execute(pdo_stmt_t *stmt)
260261
SQLRowCount(S->stmt, &row_count);
261262
stmt->row_count = row_count;
262263

263-
if (!stmt->executed) {
264+
if (S->cols == NULL) {
264265
/* do first-time-only definition of bind/mapping stuff */
265266
SQLSMALLINT colcount;
266267

267268
/* how many columns do we have ? */
268269
SQLNumResultCols(S->stmt, &colcount);
269270

270-
stmt->column_count = (int)colcount;
271+
stmt->column_count = S->col_count = (int)colcount;
271272
S->cols = ecalloc(colcount, sizeof(pdo_odbc_column));
272273
S->going_long = 0;
273274
}
@@ -845,13 +846,25 @@ static int odbc_stmt_next_rowset(pdo_stmt_t *stmt)
845846
free_cols(stmt, S);
846847
/* how many columns do we have ? */
847848
SQLNumResultCols(S->stmt, &colcount);
848-
stmt->column_count = (int)colcount;
849+
stmt->column_count = S->col_count = (int)colcount;
849850
S->cols = ecalloc(colcount, sizeof(pdo_odbc_column));
850851
S->going_long = 0;
851852

852853
return 1;
853854
}
854855

856+
static int odbc_stmt_close_cursor(pdo_stmt_t *stmt)
857+
{
858+
SQLRETURN rc;
859+
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
860+
861+
rc = SQLCloseCursor(S->stmt);
862+
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
863+
return 0;
864+
}
865+
return 1;
866+
}
867+
855868
const struct pdo_stmt_methods odbc_stmt_methods = {
856869
odbc_stmt_dtor,
857870
odbc_stmt_execute,
@@ -862,5 +875,6 @@ const struct pdo_stmt_methods odbc_stmt_methods = {
862875
odbc_stmt_set_param,
863876
odbc_stmt_get_attr, /* get attr */
864877
NULL, /* get column meta */
865-
odbc_stmt_next_rowset
878+
odbc_stmt_next_rowset,
879+
odbc_stmt_close_cursor
866880
};

ext/pdo_odbc/php_pdo_odbc_int.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ typedef struct {
149149
zend_ulong convbufsize;
150150
unsigned going_long:1;
151151
unsigned assume_utf8:1;
152-
unsigned _spare:30;
152+
signed col_count:16;
153+
unsigned _spare:14;
153154
} pdo_odbc_stmt;
154155

155156
typedef struct {

0 commit comments

Comments
 (0)