tony2001 Sun Jul 30 20:50:53 2006 UTC Added files: /php-src/ext/oci8/tests bug38173.phpt
Modified files: /php-src/ext/oci8 php_oci8_int.h oci8_statement.c oci8_interface.c Log: fix #38173 (Freeing nested cursors causes OCI8 to segfault) http://cvs.php.net/viewvc.cgi/php-src/ext/oci8/php_oci8_int.h?r1=1.16&r2=1.17&diff_format=u Index: php-src/ext/oci8/php_oci8_int.h diff -u php-src/ext/oci8/php_oci8_int.h:1.16 php-src/ext/oci8/php_oci8_int.h:1.17 --- php-src/ext/oci8/php_oci8_int.h:1.16 Wed Jun 7 13:36:19 2006 +++ php-src/ext/oci8/php_oci8_int.h Sun Jul 30 20:50:53 2006 @@ -25,7 +25,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_oci8_int.h,v 1.16 2006/06/07 13:36:19 tony2001 Exp $ */ +/* $Id: php_oci8_int.h,v 1.17 2006/07/30 20:50:53 tony2001 Exp $ */ #if HAVE_OCI8 # ifndef PHP_OCI8_INT_H @@ -166,6 +166,7 @@ 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; /* }}} */ http://cvs.php.net/viewvc.cgi/php-src/ext/oci8/oci8_statement.c?r1=1.19&r2=1.20&diff_format=u Index: php-src/ext/oci8/oci8_statement.c diff -u php-src/ext/oci8/oci8_statement.c:1.19 php-src/ext/oci8/oci8_statement.c:1.20 --- php-src/ext/oci8/oci8_statement.c:1.19 Wed Apr 12 19:22:12 2006 +++ php-src/ext/oci8/oci8_statement.c Sun Jul 30 20:50:53 2006 @@ -25,7 +25,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: oci8_statement.c,v 1.19 2006/04/12 19:22:12 tony2001 Exp $ */ +/* $Id: oci8_statement.c,v 1.20 2006/07/30 20:50:53 tony2001 Exp $ */ #ifdef HAVE_CONFIG_H @@ -94,6 +94,7 @@ statement->connection = connection; statement->has_data = 0; + statement->nested = 0; if (OCI_G(default_prefetch) > 0) { php_oci_statement_set_prefetch(statement, OCI_G(default_prefetch) TSRMLS_CC); @@ -443,6 +444,7 @@ case SQLT_RSET: outcol->statement = php_oci_statement_create(statement->connection, NULL, 0, 0 TSRMLS_CC); outcol->stmtid = outcol->statement->id; + outcol->statement->nested = 1; define_type = SQLT_RSET; outcol->is_cursor = 1; http://cvs.php.net/viewvc.cgi/php-src/ext/oci8/oci8_interface.c?r1=1.16&r2=1.17&diff_format=u Index: php-src/ext/oci8/oci8_interface.c diff -u php-src/ext/oci8/oci8_interface.c:1.16 php-src/ext/oci8/oci8_interface.c:1.17 --- php-src/ext/oci8/oci8_interface.c:1.16 Mon Jun 5 07:34:00 2006 +++ php-src/ext/oci8/oci8_interface.c Sun Jul 30 20:50:53 2006 @@ -25,7 +25,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: oci8_interface.c,v 1.16 2006/06/05 07:34:00 tony2001 Exp $ */ +/* $Id: oci8_interface.c,v 1.17 2006/07/30 20:50:53 tony2001 Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -1479,7 +1479,10 @@ } PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement); - zend_list_delete(statement->id); + if (!statement->nested) { + /* nested cursors cannot be freed, they are allocated once and used during the fetch */ + zend_list_delete(statement->id); + } RETURN_TRUE; } http://cvs.php.net/viewvc.cgi/php-src/ext/oci8/tests/bug38173.phpt?view=markup&rev=1.1 Index: php-src/ext/oci8/tests/bug38173.phpt +++ php-src/ext/oci8/tests/bug38173.phpt --TEST-- Bug #38173 (Freeing nested cursors causes OCI8 to segfault) --SKIPIF-- <?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?> --FILE-- <?php require dirname(__FILE__)."/connect.inc"; $create_1 = "CREATE TABLE t1 (id INTEGER)"; $create_2 = "CREATE TABLE t2 (id INTEGER)"; $drop_1 = "DROP TABLE t1"; $drop_2 = "DROP TABLE t2"; $s1 = oci_parse($c, $drop_1); $s2 = oci_parse($c, $drop_2); @oci_execute($s1); @oci_execute($s2); $s1 = oci_parse($c, $create_1); $s2 = oci_parse($c, $create_2); oci_execute($s1); oci_execute($s2); for($i=0; $i < 5; $i++) { $insert = "INSERT INTO t1 VALUES(".$i.")"; $s = oci_parse($c, $insert); oci_execute($s); } for($i=0; $i < 5; $i++) { $insert = "INSERT INTO t2 VALUES(".$i.")"; $s = oci_parse($c, $insert); oci_execute($s); } $query =" SELECT t1.*, CURSOR( SELECT * FROM t2 ) as cursor FROM t1 "; $sth = oci_parse($c, $query); oci_execute($sth); // dies on oci_free_statement on 2nd pass through loop while ( $row = oci_fetch_assoc($sth) ) { print "Got row!\n"; var_dump(oci_execute($row['CURSOR'])); var_dump(oci_free_statement($row['CURSOR'])); } $s1 = oci_parse($c, $drop_1); $s2 = oci_parse($c, $drop_2); @oci_execute($s1); @oci_execute($s2); echo "Done\n"; ?> --EXPECT-- Got row! bool(true) bool(true) Got row! bool(true) bool(true) Got row! bool(true) bool(true) Got row! bool(true) bool(true) Got row! bool(true) bool(true) Done -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php