php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #42841 oci_new_cursor PHP crash
Submitted: 2007-10-03 15:39 UTC Modified: 2008-01-31 00:38 UTC
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:0 (0.0%)
From: pr0head at gmail dot com Assigned:
Status: Closed Package: OCI8 related
PHP Version: 5.2.4 OS: Linux version 2.6.20-gentoo-r8
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: pr0head at gmail dot com
New email:
PHP Version: OS:

 

 [2007-10-03 15:39 UTC] pr0head at gmail dot com
Description:
------------
If you have two or more times the same stored procedure where the cursor name the same ( :cursor ), PHP stop work.

Reproduce code:
---------------
$connection = oci_connect( .... );

// First execute SP
$sql = "BEGIN sp_vadik_1( :cursor ); END;";
$stmt = oci_parse( $connection, $sql );
$cursor = oci_new_cursor( $connection );
oci_bind_by_name( $stmt, ":cursor", $cursor, -1, OCI_B_CURSOR );

oci_execute( $stmt, OCI_DEFAULT );
oci_execute( $cursor );

while( $row = oci_fetch_array( $cursor ) ) { .... }

oci_free_statement( $stmt );
oci_free_statement( $cursor );

Expected result:
----------------
If the cursor names are not different ( first - :cursor1, second - :cursor2), the challenges are successful.

If not cleaned cursor to the first call, and declare it in the second, the queries are also successful.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-10-04 00:27 UTC] sixd@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.


+------------------------------------------------------------
| I couldn't reproduce it.
| Thanks for reporting the bug, but please include a complete
| testcase so I don't have to guess what the code might be.
| Also, what does "stop work" mean?
+------------------------------------------------------------
 [2007-10-04 08:14 UTC] pr0head at gmail dot com
<?php

/**
* ORACLE Storage Procedure
*
* create or replace procedure sp_vadik_1 ( out_1 out sys_refcursor ) is begin
* open out_1 for select 11 from dual union all select 12 from dual union all select 13 from dual;
* end sp_vadik_1; 
*/

$params_db = array( 'host' => "localhost", 'username' => "username", 'password' => "password", 'dbname' => "db" );

putenv( 'ORACLE_SID=' . $params_db['dbname'] );
$conn_string = '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=' . $params_db['host'] . ')(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=' . $params_db['dbname'] . ')))';

$connection = @oci_connect( $params_db['username'], $params_db['password'], $conn_string );



//------------ START EXECUTE 1 ---------------//
$sql = "BEGIN sp_vadik_1( :cursor ); END;";
$stmt = oci_parse( $connection, $sql );
$cursor = oci_new_cursor( $connection );
oci_bind_by_name( $stmt, ":cursor", $cursor, -1, OCI_B_CURSOR );

oci_execute( $stmt, OCI_DEFAULT );
oci_execute( $cursor );

while( $row = oci_fetch_array( $cursor, OCI_ASSOC + OCI_RETURN_LOBS ) )
{
    $data[] = $row;
}

oci_free_statement( $stmt );
oci_free_statement( $cursor );
//------------ STOP EXECUTE 1 ---------------//



//------------ START EXECUTE 2 ---------------//
$sql = "BEGIN sp_vadik_1( :cursor1 ); END;";
$stmt = oci_parse( $connection, $sql );
$cursor = oci_new_cursor( $connection );
oci_bind_by_name( $stmt, ":cursor1", $cursor, -1, OCI_B_CURSOR );

oci_execute( $stmt, OCI_DEFAULT );
oci_execute( $cursor );

while( $row = oci_fetch_array( $cursor, OCI_ASSOC + OCI_RETURN_LOBS ) )
{
    $data[] = $row;
}

oci_free_statement( $stmt );
oci_free_statement( $cursor );
var_dump($cur2);
//------------ STOP EXECUTE 2 ---------------//

oci_close( $connection );


?>
 [2007-10-04 08:27 UTC] pr0head at gmail dot com
Sorry, need change lines in EXECUTE 2 (for reproduction errors).
SQL and bind param must be the same for both executions:

$sql = "BEGIN sp_vadik_1( :cursor ); END;";
oci_bind_by_name( $stmt, ":cursor", $cursor, -1, OCI_B_CURSOR );
 [2007-10-04 08:38 UTC] pr0head at gmail dot com
"stop work" - this crash PHP.
If run this script in command line, i see error "segmentation false"
 [2007-11-12 10:35 UTC] tony2001@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a backtrace to see what is happening behind the scenes. To
find out how to generate a backtrace, please read
http://bugs.php.net/bugs-generating-backtrace.php for *NIX and
http://bugs.php.net/bugs-generating-backtrace-win32.php for Win32

Once you have generated a backtrace, please submit it to this bug
report and change the status back to "Open". Thank you for helping
us make PHP better.


 [2007-11-20 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2007-11-20 09:46 UTC] pr0head at gmail dot com
This script working normally if not reopen cursor.

Bad result:
$sql = "BEGIN sp_vadik_1( :cursor ); END;";
$stmt = oci_parse( $connection, $sql );
$cursor = oci_new_cursor( $connection );
oci_bind_by_name( $stmt, ":cursor", $cursor, -1, OCI_B_CURSOR );
oci_execute( $stmt, OCI_DEFAULT );
oci_execute( $cursor );
oci_free_statement( $stmt );
oci_free_statement( $cursor );

$sql = "BEGIN sp_vadik_1( :cursor ); END;";
$stmt = oci_parse( $connection, $sql );
$cursor = oci_new_cursor( $connection );
oci_bind_by_name( $stmt, ":cursor", $cursor, -1, OCI_B_CURSOR );
oci_execute( $stmt, OCI_DEFAULT );
oci_execute( $cursor );
oci_free_statement( $stmt );
oci_free_statement( $cursor );

Good result:
$sql = "BEGIN sp_vadik_1( :cursor ); END;";
$stmt = oci_parse( $connection, $sql );
$cursor = oci_new_cursor( $connection );
oci_bind_by_name( $stmt, ":cursor", $cursor, -1, OCI_B_CURSOR );
oci_execute( $stmt, OCI_DEFAULT );
oci_execute( $cursor );
oci_free_statement( $stmt );

$sql = "BEGIN sp_vadik_1( :cursor ); END;";
$stmt = oci_parse( $connection, $sql );
oci_bind_by_name( $stmt, ":cursor", $cursor, -1, OCI_B_CURSOR );
oci_execute( $stmt, OCI_DEFAULT );
oci_execute( $cursor );
oci_free_statement( $stmt );
oci_free_statement( $cursor );
 [2007-12-11 20:39 UTC] sixd@php.net
I reproduced the crash.  The problem appears to be the same as reported in http://bugs.php.net/bug.php?id=43340.  If you change the PL/SQL package definition so out_1 is an "IN OUT" parameter, there is no crash.
 [2007-12-14 18:53 UTC] michael dot virnstein at brodos dot de
This fix only works for out parameters, not for return values from functions. I can't change thosea.
I also filed the bug (Bug #43449), haven't found the other two.
 [2008-01-09 19:40 UTC] sixd@php.net
The original testcase (with the parameter only as OUT) does not crash with OCI8 1.3.0 Beta from PECL.
 [2008-01-30 18:49 UTC] sixd@php.net
This was a latent bug exposed when statement caching was fixed.
The temporary workaround is to set oci8.statement_cache_size=0

The real solution (thanks to Sree) is to add a missing case for
cursors to the out-bind callback:

diff -u oci8_statement.c.orig oci8_statement.c
--- oci8_statement.c.orig	2008-01-30 10:37:32.000000000 -0800
+++ oci8_statement.c	2008-01-30 10:21:31.000000000 -0800
@@ -1174,6 +1174,14 @@
 	}
 
 	if (Z_TYPE_P(val) == IS_RESOURCE) {
+		/* Processing for ref-cursor out binds */
+		if (phpbind->statement != NULL) {
+			*bufpp = phpbind->statement;
+			*alenpp = &phpbind->dummy_len;
+			*piecep = OCI_ONE_PIECE;
+			*rcodepp = &phpbind->retcode;
+			*indpp = &phpbind->indicator;
+		}
 		retval = OCI_CONTINUE;
 	} else if (Z_TYPE_P(val) == IS_OBJECT) {
 		if (!phpbind->descriptor) {


 [2008-01-31 00:38 UTC] sixd@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 15:01:30 2024 UTC