diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2020-02-17 22:55:16 +0100 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2020-02-17 22:55:16 +0100 |
commit | 72737b066007fa22dd341f0df9092c18f6e5a15c (patch) | |
tree | a5c30225d956686f6da16ad3cf244eafad82bdba /ext/pdo_odbc | |
parent | 4804dc2b20c2e9387500808cceafa6fc556a9bd2 (diff) | |
parent | 3090c88f55f53d0a8af4e9dbec2664a24c1fa702 (diff) | |
download | php-git-72737b066007fa22dd341f0df9092c18f6e5a15c.tar.gz |
Merge branch 'PHP-7.4'
* PHP-7.4:
Fix #79038: PDOStatement::nextRowset() leaks column values
Diffstat (limited to 'ext/pdo_odbc')
-rw-r--r-- | ext/pdo_odbc/odbc_stmt.c | 24 | ||||
-rw-r--r-- | ext/pdo_odbc/php_pdo_odbc_int.h | 3 |
2 files changed, 21 insertions, 6 deletions
diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index 799ef02e48..610c6121c5 100644 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -124,13 +124,14 @@ static void free_cols(pdo_stmt_t *stmt, pdo_odbc_stmt *S) if (S->cols) { int i; - for (i = 0; i < stmt->column_count; i++) { + for (i = 0; i < S->col_count; i++) { if (S->cols[i].data) { efree(S->cols[i].data); } } efree(S->cols); S->cols = NULL; + S->col_count = 0; } } @@ -260,14 +261,14 @@ static int odbc_stmt_execute(pdo_stmt_t *stmt) SQLRowCount(S->stmt, &row_count); stmt->row_count = row_count; - if (!stmt->executed) { + if (S->cols == NULL) { /* do first-time-only definition of bind/mapping stuff */ SQLSMALLINT colcount; /* how many columns do we have ? */ 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->going_long = 0; } @@ -845,13 +846,25 @@ static int odbc_stmt_next_rowset(pdo_stmt_t *stmt) free_cols(stmt, S); /* how many columns do we have ? */ 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->going_long = 0; 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 = { odbc_stmt_dtor, odbc_stmt_execute, @@ -862,5 +875,6 @@ const struct pdo_stmt_methods odbc_stmt_methods = { odbc_stmt_set_param, odbc_stmt_get_attr, /* get attr */ NULL, /* get column meta */ - odbc_stmt_next_rowset + odbc_stmt_next_rowset, + odbc_stmt_close_cursor }; diff --git a/ext/pdo_odbc/php_pdo_odbc_int.h b/ext/pdo_odbc/php_pdo_odbc_int.h index 5604e86273..db033b25b3 100644 --- a/ext/pdo_odbc/php_pdo_odbc_int.h +++ b/ext/pdo_odbc/php_pdo_odbc_int.h @@ -149,7 +149,8 @@ typedef struct { zend_ulong convbufsize; unsigned going_long:1; unsigned assume_utf8:1; - unsigned _spare:30; + signed col_count:16; + unsigned _spare:14; } pdo_odbc_stmt; typedef struct { |