summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorChristopher Jones <sixd@php.net>2008-02-25 23:50:51 +0000
committerChristopher Jones <sixd@php.net>2008-02-25 23:50:51 +0000
commitb4b099ae1971a3987b83ef64f96b91e7cb6ddd81 (patch)
treee132736ec54b941f9b682c0aec11372fc530232c /ext
parent6e46f25b129ba5e1575b2160e1168bf4d017e1ca (diff)
downloadphp-git-b4b099ae1971a3987b83ef64f96b91e7cb6ddd81.tar.gz
MFH: OCI8: fix bug #44008 (OCI-Lob->close) & bug #44206 (ref cursor leak)
Diffstat (limited to 'ext')
-rw-r--r--ext/oci8/oci8_interface.c9
-rw-r--r--ext/oci8/oci8_lob.c7
-rw-r--r--ext/oci8/oci8_statement.c3
-rw-r--r--ext/oci8/php_oci8_int.h3
-rw-r--r--ext/oci8/tests/bug43492_2.phpt369
-rw-r--r--ext/oci8/tests/bug44008.phpt54
-rw-r--r--ext/oci8/tests/bug44206.phpt43
-rw-r--r--ext/oci8/tests/lob_014.phpt4
-rw-r--r--ext/oci8/tests/lob_021.phpt6
9 files changed, 483 insertions, 15 deletions
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--
+<?php if (!extension_loaded('oci8')) die ("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+// This test is similar to bug43492.phpt without the explict free.
+// Now that bug 44206 is fixed an automatic clean up will occur -
+// though it is still recommended in practice.
+
+require dirname(__FILE__).'/connect.inc';
+
+$stmtarray = array(
+ "DROP table bug43492_tab",
+ "CREATE TABLE bug43492_tab(col1 VARCHAR2(1))",
+ "INSERT INTO bug43492_tab VALUES ('A')",
+ "INSERT INTO bug43492_tab VALUES ('B')",
+ "INSERT INTO bug43492_tab VALUES ('C')",
+ "INSERT INTO bug43492_tab VALUES ('D')",
+ "INSERT INTO bug43492_tab VALUES ('E')",
+ "INSERT INTO bug43492_tab VALUES ('F')",
+ "INSERT INTO bug43492_tab VALUES ('G')",
+ "INSERT INTO bug43492_tab VALUES ('H')",
+ "INSERT INTO bug43492_tab VALUES ('I')",
+ "INSERT INTO bug43492_tab VALUES ('J')"
+);
+
+foreach ($stmtarray as $stmt) {
+ $s = oci_parse($c, $stmt);
+ @oci_execute($s);
+}
+
+function fetch($c, $i) {
+ $s = ociparse($c, 'select cursor(select * from bug43492_tab) c from bug43492_tab');
+ ociexecute($s, OCI_DEFAULT);
+ ocifetchinto($s, $result, OCI_ASSOC);
+ ociexecute($result['C'], OCI_DEFAULT);
+ return $result['C'];
+}
+
+for($i = 0; $i < 300; $i++) {
+ $cur = fetch($c, $i);
+ for($j = 0; $j < 10; $j++) {
+ ocifetchinto($cur, $row, OCI_NUM);
+ echo "$row[0] ";
+ }
+ echo "\n";
+ ocifreestatement($cur);
+}
+
+echo "Done\n";
+
+// Cleanup
+
+$stmtarray = array(
+ "DROP table bug43492_tab"
+);
+
+foreach ($stmtarray as $stmt) {
+ $s = oci_parse($c, $stmt);
+ @oci_execute($s);
+}
+
+oci_close($c);
+
+?>
+--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--
+<?php if (!extension_loaded('oci8')) die ("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+// Initialization
+
+$stmtarray = array(
+ "create or replace procedure bug44008_proc (p in out clob)
+ as begin p := 'A';
+ end;"
+);
+
+foreach ($stmtarray as $stmt) {
+ $s = oci_parse($c, $stmt);
+ @oci_execute($s);
+}
+
+// Run Test
+
+$s = oci_parse($c, 'begin bug44008_proc(:data); end;');
+$textLob = oci_new_descriptor($c, OCI_D_LOB);
+oci_bind_by_name($s, ":data", $textLob, -1, OCI_B_CLOB);
+oci_execute($s, OCI_DEFAULT);
+$r = $textLob->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--
+<?php if (!extension_loaded('oci8')) die ("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+// Run Test
+
+for ($x = 0; $x < 400; $x++)
+{
+ $stmt = "select cursor (select $x from dual) a,
+ cursor (select $x from dual) b
+ from dual";
+ $s = oci_parse($c, $stmt);
+ $r = oci_execute($s);
+ if (!$r) {
+ echo "Exiting $x\n";
+ exit;
+ }
+ $mode = OCI_ASSOC | OCI_RETURN_NULLS;
+ $result = oci_fetch_array($s, $mode);
+ oci_execute($result['A']);
+ oci_execute($result['B']);
+ oci_fetch_array($result['A'], $mode);
+ oci_fetch_array($result['B'], $mode);
+ oci_free_statement($result['A']);
+ oci_free_statement($result['B']);
+ oci_free_statement($s);
+}
+
+echo "Completed $x\n";
+
+oci_close($c);
+
+echo "Done\n";
+
+?>
+--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)