Skip to content

Avoid hardly debugable PHP.exe crashes #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 30, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 41 additions & 28 deletions ibase_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,16 @@ typedef struct {
unsigned short el_type, el_size;
} ibase_array;

typedef struct {
ibase_db_link* link;
isc_stmt_handle stmt;
} ibase_statement;

typedef struct {
ibase_db_link *link;
ibase_trans *trans;
struct _ib_query *query;
isc_stmt_handle stmt;
zend_resource* stmt_res;
unsigned short type;
unsigned char has_more_rows, statement_type;
XSQLDA *out_sqlda;
Expand All @@ -60,9 +65,9 @@ typedef struct {
typedef struct _ib_query {
ibase_db_link *link;
ibase_trans *trans;
ibase_result *result;
zend_resource *result_res;
isc_stmt_handle stmt;
zend_resource *stmt_res;
XSQLDA *in_sqlda, *out_sqlda;
ibase_array *in_array, *out_array;
unsigned short in_array_cnt, out_array_cnt;
Expand Down Expand Up @@ -94,7 +99,7 @@ typedef struct {
short sqlind;
} BIND_BUF;

static int le_result, le_query;
static int le_statement, le_result, le_query;

#define LE_RESULT "Firebird/InterBase result"
#define LE_QUERY "Firebird/InterBase query"
Expand All @@ -119,20 +124,25 @@ static void _php_ibase_free_xsqlda(XSQLDA *sqlda) /* {{{ */
}
/* }}} */

static void _php_ibase_free_stmt_handle(ibase_db_link *link, isc_stmt_handle stmt) /* {{{ */
static void _php_ibase_free_statement(zend_resource* rsrc) /* {{{ */
{
static char info[] = { isc_info_base_level, isc_info_end };

if (stmt) {
char res_buf[8];
IBDEBUG("Dropping statement handle (free_stmt_handle)...");
/* Only free statement if db-connection is still open */
if (SUCCESS == isc_database_info(IB_STATUS, &link->handle,
sizeof(info), info, sizeof(res_buf), res_buf)) {
if (isc_dsql_free_statement(IB_STATUS, &stmt, DSQL_drop)) {
_php_ibase_error();
ibase_statement* ib_stmt = (ibase_statement*)rsrc->ptr;

IBDEBUG("Freeing statement by dtor...");
if (ib_stmt) {
if (ib_stmt->stmt) {
static char info[] = { isc_info_base_level, isc_info_end };
char res_buf[8];
IBDEBUG("Dropping statement handle (free_stmt_handle)...");
/* Only free statement if db-connection is still open */
if (SUCCESS == isc_database_info(IB_STATUS, &ib_stmt->link->handle,
sizeof(info), info, sizeof(res_buf), res_buf)) {
if (isc_dsql_free_statement(IB_STATUS, &ib_stmt->stmt, DSQL_drop)) {
_php_ibase_error();
}
}
}
efree(ib_stmt);
}
}
/* }}} */
Expand All @@ -144,11 +154,9 @@ static void _php_ibase_free_result(zend_resource *rsrc) /* {{{ */
IBDEBUG("Freeing result by dtor...");
if (ib_result) {
_php_ibase_free_xsqlda(ib_result->out_sqlda);
if (ib_result->query != NULL) {
IBDEBUG("query still valid; don't drop statement handle");
ib_result->query->result = NULL; /* Indicate to query, that result is released */
} else {
_php_ibase_free_stmt_handle(ib_result->link, ib_result->stmt);
if (ib_result->stmt_res != NULL) {
zend_list_delete(ib_result->stmt_res);
ib_result->stmt_res == NULL;
}
efree(ib_result);
}
Expand All @@ -165,11 +173,9 @@ static void _php_ibase_free_query(ibase_query *ib_query) /* {{{ */
if (ib_query->out_sqlda) {
efree(ib_query->out_sqlda);
}
if (ib_query->result != NULL) {
IBDEBUG("result still valid; don't drop statement handle");
ib_query->result->query = NULL; /* Indicate to result, that query is released */
} else {
_php_ibase_free_stmt_handle(ib_query->link, ib_query->stmt);
if (ib_query->stmt_res != NULL) {
zend_list_delete(ib_query->stmt_res);
ib_query->stmt_res == NULL;
}
if (ib_query->in_array) {
efree(ib_query->in_array);
Expand Down Expand Up @@ -197,6 +203,8 @@ static void php_ibase_free_query_rsrc(zend_resource *rsrc) /* {{{ */

void php_ibase_query_minit(INIT_FUNC_ARGS) /* {{{ */
{
le_statement = zend_register_list_destructors_ex(_php_ibase_free_statement, NULL,
"interbase statement", module_number);
le_result = zend_register_list_destructors_ex(_php_ibase_free_result, NULL,
"interbase result", module_number);
le_query = zend_register_list_destructors_ex(php_ibase_free_query_rsrc, NULL,
Expand Down Expand Up @@ -334,8 +342,8 @@ static int _php_ibase_alloc_query(ibase_query *ib_query, ibase_db_link *link, /*
ib_query->link = link;
ib_query->trans = trans;
ib_query->result_res = NULL;
ib_query->result = NULL;
ib_query->stmt = 0;
ib_query->stmt_res = NULL;
ib_query->in_array = NULL;
ib_query->out_array = NULL;
ib_query->dialect = dialect;
Expand All @@ -348,6 +356,12 @@ static int _php_ibase_alloc_query(ibase_query *ib_query, ibase_db_link *link, /*
_php_ibase_error();
goto _php_ibase_alloc_query_error;
}
{ /* allocate zend resource for statement*/
ibase_statement* ib_stmt = emalloc(sizeof(ibase_statement));
ib_stmt->link = link;
ib_stmt->stmt = ib_query->stmt;
ib_query->stmt_res = zend_register_resource(ib_stmt, le_statement);
}

ib_query->out_sqlda = (XSQLDA *) emalloc(XSQLDA_LENGTH(1));
ib_query->out_sqlda->sqln = 1;
Expand Down Expand Up @@ -997,9 +1011,8 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul
res->link = ib_query->link;
res->trans = ib_query->trans;
res->stmt = ib_query->stmt;
/* ib_result and ib_query point at each other to handle release of statement handle properly */
res->query = ib_query;
ib_query->result = res;
GC_ADDREF(res->stmt_res = ib_query->stmt_res);

res->statement_type = ib_query->statement_type;
res->has_more_rows = 1;

Expand Down