Merge branch 'PHP-7.3' into PHP-7.4

* PHP-7.3:
  Fix #79038: PDOStatement::nextRowset() leaks column values
This commit is contained in:
Christoph M. Becker 2020-02-17 22:53:50 +01:00
commit 3090c88f55
3 changed files with 24 additions and 6 deletions

3
NEWS
View file

@ -29,6 +29,9 @@ PHP NEWS
. Fixed bug #79257 (Duplicate named groups (?J) prefer last alternative even . Fixed bug #79257 (Duplicate named groups (?J) prefer last alternative even
if not matched). (Nikita) if not matched). (Nikita)
- PDO_ODBC:
. Fixed bug #79038 (PDOStatement::nextRowset() leaks column values). (cmb)
- Standard: - Standard:
. Fixed bug #79254 (getenv() w/o arguments not showing changes). (cmb) . Fixed bug #79254 (getenv() w/o arguments not showing changes). (cmb)

View file

@ -126,13 +126,14 @@ static void free_cols(pdo_stmt_t *stmt, pdo_odbc_stmt *S)
if (S->cols) { if (S->cols) {
int i; int i;
for (i = 0; i < stmt->column_count; i++) { for (i = 0; i < S->col_count; i++) {
if (S->cols[i].data) { if (S->cols[i].data) {
efree(S->cols[i].data); efree(S->cols[i].data);
} }
} }
efree(S->cols); efree(S->cols);
S->cols = NULL; S->cols = NULL;
S->col_count = 0;
} }
} }
@ -262,14 +263,14 @@ static int odbc_stmt_execute(pdo_stmt_t *stmt)
SQLRowCount(S->stmt, &row_count); SQLRowCount(S->stmt, &row_count);
stmt->row_count = row_count; stmt->row_count = row_count;
if (!stmt->executed) { if (S->cols == NULL) {
/* do first-time-only definition of bind/mapping stuff */ /* do first-time-only definition of bind/mapping stuff */
SQLSMALLINT colcount; SQLSMALLINT colcount;
/* how many columns do we have ? */ /* how many columns do we have ? */
SQLNumResultCols(S->stmt, &colcount); SQLNumResultCols(S->stmt, &colcount);
stmt->column_count = (int)colcount; stmt->column_count = S->col_count = (int)colcount;
S->cols = ecalloc(colcount, sizeof(pdo_odbc_column)); S->cols = ecalloc(colcount, sizeof(pdo_odbc_column));
S->going_long = 0; S->going_long = 0;
} }
@ -847,13 +848,25 @@ static int odbc_stmt_next_rowset(pdo_stmt_t *stmt)
free_cols(stmt, S); free_cols(stmt, S);
/* how many columns do we have ? */ /* how many columns do we have ? */
SQLNumResultCols(S->stmt, &colcount); SQLNumResultCols(S->stmt, &colcount);
stmt->column_count = (int)colcount; stmt->column_count = S->col_count = (int)colcount;
S->cols = ecalloc(colcount, sizeof(pdo_odbc_column)); S->cols = ecalloc(colcount, sizeof(pdo_odbc_column));
S->going_long = 0; S->going_long = 0;
return 1; return 1;
} }
static int odbc_stmt_close_cursor(pdo_stmt_t *stmt)
{
SQLRETURN rc;
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
rc = SQLCloseCursor(S->stmt);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
return 0;
}
return 1;
}
const struct pdo_stmt_methods odbc_stmt_methods = { const struct pdo_stmt_methods odbc_stmt_methods = {
odbc_stmt_dtor, odbc_stmt_dtor,
odbc_stmt_execute, odbc_stmt_execute,
@ -864,5 +877,6 @@ const struct pdo_stmt_methods odbc_stmt_methods = {
odbc_stmt_set_param, odbc_stmt_set_param,
odbc_stmt_get_attr, /* get attr */ odbc_stmt_get_attr, /* get attr */
NULL, /* get column meta */ NULL, /* get column meta */
odbc_stmt_next_rowset odbc_stmt_next_rowset,
odbc_stmt_close_cursor
}; };

View file

@ -151,7 +151,8 @@ typedef struct {
zend_ulong convbufsize; zend_ulong convbufsize;
unsigned going_long:1; unsigned going_long:1;
unsigned assume_utf8:1; unsigned assume_utf8:1;
unsigned _spare:30; signed col_count:16;
unsigned _spare:14;
} pdo_odbc_stmt; } pdo_odbc_stmt;
typedef struct { typedef struct {