diff --git a/NEWS b/NEWS index de5109dd05ce..72042349ceb9 100644 --- a/NEWS +++ b/NEWS @@ -125,6 +125,8 @@ PHP NEWS - ODBC: . Fixed bug GH-24736 (php_odbc_connstr_is_quoted() treats a value with no closing brace as quoted). (lazerg) + . Fixed bug GH-25036 (odbc_prepare() corrupts the heap when the driver + cannot describe a parameter). (Ilia Alshanetsky) - Opcache: . Fixed tracing JIT returning a wrapped integer instead of a float on diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 798245c4ca99..20302d56cb8b 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -997,6 +997,7 @@ PHP_FUNCTION(odbc_prepare) } result->conn_ptr = conn; result->fetched = 0; + odbc_insert_new_result(conn, return_value); result->param_info = (odbc_param_info *) safe_emalloc(sizeof(odbc_param_info), result->numparams, 0); for (i=0;inumparams;i++) { @@ -1004,14 +1005,11 @@ PHP_FUNCTION(odbc_prepare) &result->param_info[i].scale, &result->param_info[i].nullable); if (rc == SQL_ERROR) { odbc_sql_error(result->conn_ptr, result->stmt, "SQLDescribeParameter"); - SQLFreeStmt(result->stmt, SQL_RESET_PARAMS); - efree(result->param_info); + odbc_result_free(result); zval_ptr_dtor(return_value); RETURN_FALSE; } } - - odbc_insert_new_result(conn, return_value); } /* }}} */ diff --git a/ext/odbc/tests/gh25036.phpt b/ext/odbc/tests/gh25036.phpt new file mode 100644 index 000000000000..16b3226361cb --- /dev/null +++ b/ext/odbc/tests/gh25036.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-25036 (odbc_prepare() double free when SQLDescribeParam() fails) +--EXTENSIONS-- +odbc +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +Warning: odbc_prepare(): SQL error: %s, SQL state %s in SQLDescribeParameter in %s on line %d +bool(false) + +Warning: odbc_prepare(): SQL error: %s, SQL state %s in SQLDescribeParameter in %s on line %d +bool(false) +array(1) { + ["a"]=> + string(1) "1" +} +Error: ODBC result has already been closed