Skip to content

Commit 9b6a8e8

Browse files
author
Martin Köditz
authored
Merge pull request #16 from KoudelkaB/master
Avoid hardly debugable PHP.exe crashes
2 parents 23e2928 + d3e7169 commit 9b6a8e8

File tree

1 file changed

+41
-28
lines changed

1 file changed

+41
-28
lines changed

ibase_query.c

+41-28
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,16 @@ typedef struct {
4646
unsigned short el_type, el_size;
4747
} ibase_array;
4848

49+
typedef struct {
50+
ibase_db_link* link;
51+
isc_stmt_handle stmt;
52+
} ibase_statement;
53+
4954
typedef struct {
5055
ibase_db_link *link;
5156
ibase_trans *trans;
52-
struct _ib_query *query;
5357
isc_stmt_handle stmt;
58+
zend_resource* stmt_res;
5459
unsigned short type;
5560
unsigned char has_more_rows, statement_type;
5661
XSQLDA *out_sqlda;
@@ -60,9 +65,9 @@ typedef struct {
6065
typedef struct _ib_query {
6166
ibase_db_link *link;
6267
ibase_trans *trans;
63-
ibase_result *result;
6468
zend_resource *result_res;
6569
isc_stmt_handle stmt;
70+
zend_resource *stmt_res;
6671
XSQLDA *in_sqlda, *out_sqlda;
6772
ibase_array *in_array, *out_array;
6873
unsigned short in_array_cnt, out_array_cnt;
@@ -94,7 +99,7 @@ typedef struct {
9499
short sqlind;
95100
} BIND_BUF;
96101

97-
static int le_result, le_query;
102+
static int le_statement, le_result, le_query;
98103

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

122-
static void _php_ibase_free_stmt_handle(ibase_db_link *link, isc_stmt_handle stmt) /* {{{ */
127+
static void _php_ibase_free_statement(zend_resource* rsrc) /* {{{ */
123128
{
124-
static char info[] = { isc_info_base_level, isc_info_end };
125-
126-
if (stmt) {
127-
char res_buf[8];
128-
IBDEBUG("Dropping statement handle (free_stmt_handle)...");
129-
/* Only free statement if db-connection is still open */
130-
if (SUCCESS == isc_database_info(IB_STATUS, &link->handle,
131-
sizeof(info), info, sizeof(res_buf), res_buf)) {
132-
if (isc_dsql_free_statement(IB_STATUS, &stmt, DSQL_drop)) {
133-
_php_ibase_error();
129+
ibase_statement* ib_stmt = (ibase_statement*)rsrc->ptr;
130+
131+
IBDEBUG("Freeing statement by dtor...");
132+
if (ib_stmt) {
133+
if (ib_stmt->stmt) {
134+
static char info[] = { isc_info_base_level, isc_info_end };
135+
char res_buf[8];
136+
IBDEBUG("Dropping statement handle (free_stmt_handle)...");
137+
/* Only free statement if db-connection is still open */
138+
if (SUCCESS == isc_database_info(IB_STATUS, &ib_stmt->link->handle,
139+
sizeof(info), info, sizeof(res_buf), res_buf)) {
140+
if (isc_dsql_free_statement(IB_STATUS, &ib_stmt->stmt, DSQL_drop)) {
141+
_php_ibase_error();
142+
}
134143
}
135144
}
145+
efree(ib_stmt);
136146
}
137147
}
138148
/* }}} */
@@ -144,11 +154,9 @@ static void _php_ibase_free_result(zend_resource *rsrc) /* {{{ */
144154
IBDEBUG("Freeing result by dtor...");
145155
if (ib_result) {
146156
_php_ibase_free_xsqlda(ib_result->out_sqlda);
147-
if (ib_result->query != NULL) {
148-
IBDEBUG("query still valid; don't drop statement handle");
149-
ib_result->query->result = NULL; /* Indicate to query, that result is released */
150-
} else {
151-
_php_ibase_free_stmt_handle(ib_result->link, ib_result->stmt);
157+
if (ib_result->stmt_res != NULL) {
158+
zend_list_delete(ib_result->stmt_res);
159+
ib_result->stmt_res == NULL;
152160
}
153161
efree(ib_result);
154162
}
@@ -165,11 +173,9 @@ static void _php_ibase_free_query(ibase_query *ib_query) /* {{{ */
165173
if (ib_query->out_sqlda) {
166174
efree(ib_query->out_sqlda);
167175
}
168-
if (ib_query->result != NULL) {
169-
IBDEBUG("result still valid; don't drop statement handle");
170-
ib_query->result->query = NULL; /* Indicate to result, that query is released */
171-
} else {
172-
_php_ibase_free_stmt_handle(ib_query->link, ib_query->stmt);
176+
if (ib_query->stmt_res != NULL) {
177+
zend_list_delete(ib_query->stmt_res);
178+
ib_query->stmt_res == NULL;
173179
}
174180
if (ib_query->in_array) {
175181
efree(ib_query->in_array);
@@ -197,6 +203,8 @@ static void php_ibase_free_query_rsrc(zend_resource *rsrc) /* {{{ */
197203

198204
void php_ibase_query_minit(INIT_FUNC_ARGS) /* {{{ */
199205
{
206+
le_statement = zend_register_list_destructors_ex(_php_ibase_free_statement, NULL,
207+
"interbase statement", module_number);
200208
le_result = zend_register_list_destructors_ex(_php_ibase_free_result, NULL,
201209
"interbase result", module_number);
202210
le_query = zend_register_list_destructors_ex(php_ibase_free_query_rsrc, NULL,
@@ -334,8 +342,8 @@ static int _php_ibase_alloc_query(ibase_query *ib_query, ibase_db_link *link, /*
334342
ib_query->link = link;
335343
ib_query->trans = trans;
336344
ib_query->result_res = NULL;
337-
ib_query->result = NULL;
338345
ib_query->stmt = 0;
346+
ib_query->stmt_res = NULL;
339347
ib_query->in_array = NULL;
340348
ib_query->out_array = NULL;
341349
ib_query->dialect = dialect;
@@ -348,6 +356,12 @@ static int _php_ibase_alloc_query(ibase_query *ib_query, ibase_db_link *link, /*
348356
_php_ibase_error();
349357
goto _php_ibase_alloc_query_error;
350358
}
359+
{ /* allocate zend resource for statement*/
360+
ibase_statement* ib_stmt = emalloc(sizeof(ibase_statement));
361+
ib_stmt->link = link;
362+
ib_stmt->stmt = ib_query->stmt;
363+
ib_query->stmt_res = zend_register_resource(ib_stmt, le_statement);
364+
}
351365

352366
ib_query->out_sqlda = (XSQLDA *) emalloc(XSQLDA_LENGTH(1));
353367
ib_query->out_sqlda->sqln = 1;
@@ -997,9 +1011,8 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul
9971011
res->link = ib_query->link;
9981012
res->trans = ib_query->trans;
9991013
res->stmt = ib_query->stmt;
1000-
/* ib_result and ib_query point at each other to handle release of statement handle properly */
1001-
res->query = ib_query;
1002-
ib_query->result = res;
1014+
GC_ADDREF(res->stmt_res = ib_query->stmt_res);
1015+
10031016
res->statement_type = ib_query->statement_type;
10041017
res->has_more_rows = 1;
10051018

0 commit comments

Comments
 (0)