From: Christopher Jones Date: Mon, 25 Feb 2008 23:50:51 +0000 (+0000) Subject: MFH: OCI8: fix bug #44008 (OCI-Lob->close) & bug #44206 (ref cursor leak) X-Git-Tag: BEFORE_NEW_PARAMETER_PARSE~739 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b4b099ae1971a3987b83ef64f96b91e7cb6ddd81;p=php MFH: OCI8: fix bug #44008 (OCI-Lob->close) & bug #44206 (ref cursor leak) --- diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index f093c45a1e..40efb9ce0c 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -1509,10 +1509,11 @@ PHP_FUNCTION(oci_free_statement) } PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement); - if (!statement->nested) { - /* nested cursors cannot be freed, they are allocated once and used during the fetch */ - zend_list_delete(statement->id); - } + + zend_list_delete(statement->id); + if (statement->parent_stmtid) { + zend_list_delete(statement->parent_stmtid); + } RETURN_TRUE; } diff --git a/ext/oci8/oci8_lob.c b/ext/oci8/oci8_lob.c index 1b87616df6..83a6719df0 100644 --- a/ext/oci8/oci8_lob.c +++ b/ext/oci8/oci8_lob.c @@ -88,6 +88,7 @@ php_oci_descriptor *php_oci_lob_create (php_oci_connection *connection, long typ descriptor->buffering = PHP_OCI_LOB_BUFFER_DISABLED; /* buffering is off by default */ descriptor->charset_form = SQLCS_IMPLICIT; /* default value */ descriptor->charset_id = connection->charset; + descriptor->is_open = 0; if (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE) { /* add Lobs & Files to hash. we'll flush them at the end */ @@ -571,7 +572,9 @@ int php_oci_lob_close (php_oci_descriptor *descriptor TSRMLS_DC) { php_oci_connection *connection = descriptor->connection; - PHP_OCI_CALL_RETURN(connection->errcode, OCILobClose, (connection->svc, connection->err, descriptor->descriptor)); + if (descriptor->is_open) { + PHP_OCI_CALL_RETURN(connection->errcode, OCILobClose, (connection->svc, connection->err, descriptor->descriptor)); + } if (connection->errcode != OCI_SUCCESS) { php_oci_error(connection->err, connection->errcode TSRMLS_CC); @@ -909,6 +912,8 @@ int php_oci_lob_write_tmp (php_oci_descriptor *descriptor, ub1 type, char *data, return 1; } + descriptor->is_open = 1; + return php_oci_lob_write(descriptor, 0, data, data_len, &bytes_written TSRMLS_CC); } /* }}} */ diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 17822d5b3b..a07937a9a4 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -106,7 +106,7 @@ php_oci_statement *php_oci_statement_create (php_oci_connection *connection, cha statement->connection = connection; statement->has_data = 0; - statement->nested = 0; + statement->parent_stmtid = 0; zend_list_addref(statement->connection->rsrc_id); if (OCI_G(default_prefetch) > 0) { @@ -336,6 +336,7 @@ sb4 php_oci_define_callback(dvoid *ctx, OCIDefine *define, ub4 iter, dvoid **buf if (!nested_stmt) { return OCI_ERROR; } + nested_stmt->parent_stmtid = outcol->statement->id; zend_list_addref(outcol->statement->id); outcol->nested_statement = nested_stmt; outcol->stmtid = nested_stmt->id; diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index f71d99c046..8e381e45f6 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -143,6 +143,7 @@ typedef struct { /* php_oci_descriptor {{{ */ ub4 chunk_size; /* chunk size of the LOB. 0 - unknown */ ub1 charset_form; /* charset form, required for NCLOBs */ ub2 charset_id; /* charset ID */ + unsigned is_open:1; /* helps to determine if lob is open or not */ } php_oci_descriptor; /* }}} */ typedef struct { /* php_oci_lob_ctx {{{ */ @@ -171,6 +172,7 @@ typedef struct { /* php_oci_define {{{ */ typedef struct { /* php_oci_statement {{{ */ int id; + int parent_stmtid; /* parent statement id */ php_oci_connection *connection; /* parent connection handle */ sword errcode; /* last errcode*/ OCIError *err; /* private error handle */ @@ -183,7 +185,6 @@ typedef struct { /* php_oci_statement {{{ */ int ncolumns; /* number of columns in the result */ unsigned executed:1; /* statement executed flag */ unsigned has_data:1; /* statement has more data flag */ - unsigned nested:1; /* statement handle is valid */ ub2 stmttype; /* statement type */ } php_oci_statement; /* }}} */ diff --git a/ext/oci8/tests/bug43492_2.phpt b/ext/oci8/tests/bug43492_2.phpt new file mode 100644 index 0000000000..fcf96e984e --- /dev/null +++ b/ext/oci8/tests/bug43492_2.phpt @@ -0,0 +1,369 @@ +--TEST-- +Bug #43492 (Nested cursor leaks after related bug #44206 fixed) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +A B C D E F G H I J +Done diff --git a/ext/oci8/tests/bug44008.phpt b/ext/oci8/tests/bug44008.phpt new file mode 100644 index 0000000000..fd10b26b8b --- /dev/null +++ b/ext/oci8/tests/bug44008.phpt @@ -0,0 +1,54 @@ +--TEST-- +Bug #44008 (Incorrect usage of OCI-Lob->close doesn't crash PHP) +--SKIPIF-- + +--FILE-- +load(); +echo "$r\n"; + +// Incorrectly closing the lob doesn't cause a crash. +// OCI-LOB->close() is documented for use only with OCI-Lob->writeTemporary() +$textLob->close(); + +// Cleanup + +$stmtarray = array( + "drop procedure bug44008_proc" +); + +foreach ($stmtarray as $stmt) { + $s = oci_parse($c, $stmt); + oci_execute($s); +} + +oci_close($c); + +echo "Done\n"; + +?> +--EXPECT-- +A +Done diff --git a/ext/oci8/tests/bug44206.phpt b/ext/oci8/tests/bug44206.phpt new file mode 100644 index 0000000000..e5771e4182 --- /dev/null +++ b/ext/oci8/tests/bug44206.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #44206 (Test if selecting ref cursors leads to ORA-1000 maximum open cursors reached) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Completed 400 +Done diff --git a/ext/oci8/tests/lob_014.phpt b/ext/oci8/tests/lob_014.phpt index 60ed945312..1ba29ee649 100644 --- a/ext/oci8/tests/lob_014.phpt +++ b/ext/oci8/tests/lob_014.phpt @@ -43,9 +43,7 @@ echo "Done\n"; ?> --EXPECTF-- int(4) - -Warning: OCI-Lob::close(): ORA-22289: cannot perform operation on an unopened file or LOB in %slob_014.php on line %d -bool(false) +bool(true) int(4) bool(true) diff --git a/ext/oci8/tests/lob_021.phpt b/ext/oci8/tests/lob_021.phpt index 32ef6f9fef..0ae6b377ab 100644 --- a/ext/oci8/tests/lob_021.phpt +++ b/ext/oci8/tests/lob_021.phpt @@ -20,8 +20,6 @@ $blob = oci_new_descriptor($c,OCI_D_LOB); oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB); oci_execute($statement, OCI_DEFAULT); -$blob; - var_dump($blob->write("test")); var_dump($blob->close()); var_dump($blob->write("test")); @@ -50,9 +48,7 @@ echo "Done\n"; ?> --EXPECTF-- int(4) - -Warning: OCI-Lob::close(): ORA-22289: cannot perform operation on an unopened file or LOB in %s on line %d -bool(false) +bool(true) int(4) bool(true)