php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #46050 odbc_next_result corrupts prepared resource
Submitted: 2008-09-11 13:33 UTC Modified: 2020-10-05 15:35 UTC
From: RQuadling at GMail dot com Assigned: cmb (profile)
Status: Closed Package: ODBC related
PHP Version: 5.3.0alpha2 OS: Windows XP SP3
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: RQuadling at GMail dot com
New email:
PHP Version: OS:

 

 [2008-09-11 13:33 UTC] RQuadling at GMail dot com
Description:
------------
Using PHP 5.3.0alpha3-dev (cli) (built: Sep 11 2008 09:01:08)

Using ODBC to talk to Microsoft SQL Server 7.

Using a prepared statement to run a Stored Procedure on the SQL 
server.

Using the function odbc_next_result() to determine if there are more 
result sets after having retrieved the first result sets kills the 
prepared statement from re-use and results in an unhandled win32 
exception.

The SP is not the issue and as a test is the following code:

CREATE PROCEDURE dbo.SimpleIdentity
	@s_Identity AS VARCHAR(500)
AS
	SELECT
		@s_Identity AS [Simple Identity]
GO


Removing the odbc_next_result() loop makes everything work.

The example code below is from a larger code which deals with getting 
data from an SP and caching the result(s). Currently I am unable to 
retrieve multiple result sets AND use stored procedures together.






Reproduce code:
---------------
<?php
// Configure this script.
$s_Server     = 'BANDVULCSQL';
$s_Database   = 'CONTRACTS';
$s_Username   = 'sa';
$s_Password   = 'sa';
$s_StoredProc = 'SimpleIdentity';
$a_Params     = array
	(
	'Richard',
	'Simon',
	'John',
	);

/******************************************/

// Connect to the SQL Server using a DNS-less connection.
$r_Connection = odbc_pconnect("Driver={SQL Server};Server={$s_Server};Database={$s_Database}", $s_Username, $s_Password);

// Prepare the statement.
$r_Statement = odbc_prepare($r_Connection, "EXEC {$s_Database}.dbo.{$s_StoredProc} ?");

// Execute the statement for each parameter.
foreach($a_Params as $s_Param)
	{
	echo 'About to process : ', $s_Param, PHP_EOL;
	$b_Executed = odbc_execute($r_Statement, array($s_Param));
	do
		{
		while(False !== ($a_Row = odbc_fetch_array($r_Statement)))
			{
			print_r($a_Row);
			}
		}
	while(True === ($b_MoreResults = odbc_next_result($r_Statement)));
	}



Expected result:
----------------
About to process : Richard
Array
(
    [Simple Identity] => Richard
)
About to process : Simon
Array
(
    [Simple Identity] => Simon
)
About to process : John
Array
(
    [Simple Identity] => John
)






Actual result:
--------------
About to process : Richard
Array
(
    [Simple Identity] => Richard
)
About to process : Simon

and then an unhandled win32 exception in php.cli







Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-10-24 08:58 UTC] jani@php.net
Reclassified in correct category. And you should use PDO ODBC instead anyway.
 [2010-04-12 17:40 UTC] RQuadling at GMail dot com
Using PDO-ODBC is fine.


// Connect to the SQL Server using a DNS-less connection.
// $r_Connection = odbc_pconnect("Driver={SQL 
Server};Server={$s_Server};Database={$s_Database}", $s_Username, $s_Password);
$r_Connection = new PDO("odbc:Driver={SQL Server Native Client 
10.0};Server={$s_Server};Database={$s_Database}", $s_Username, $s_Password);

// Prepare the statement.
// $r_Statement = odbc_prepare($r_Connection, "EXEC 
{$s_Database}.dbo.{$s_StoredProc} ?");
$r_Statement = $r_Connection->prepare("EXEC {$s_Database}.dbo.{$s_StoredProc} 
?");

// Execute the statement for each parameter.
foreach($a_Params as $s_Param)
	{
	echo 'About to process : ', $s_Param, PHP_EOL;
// 	$b_Executed = odbc_execute($r_Statement, array($s_Param));
	$b_Executed = $r_Statement->execute(array($s_Param));
	do
		{
// 		while(False !== ($a_Row = odbc_fetch_array($r_Statement)))
		while(False !== ($a_Row = $r_Statement-
>fetch(PDO::FETCH_ASSOC)))
			{
			print_r($a_Row);
			}
		}
// 	while(True === ($b_MoreResults = odbc_next_result($r_Statement)));
	while(True === ($b_MoreResults = $r_Statement->nextRowset()));
	$r_Statement->closeCursor();
	}
 [2010-04-23 23:13 UTC] felipe@php.net
-Status: Open +Status: Feedback
 [2010-04-23 23:13 UTC] felipe@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.


 [2010-04-26 12:23 UTC] RQuadling at GMail dot com
-Status: Feedback +Status: Open
 [2010-04-26 12:23 UTC] RQuadling at GMail dot com
As requested. Win32 Backtrace.


php__PID__3656__Date__04_26_2010__Time_11_19_52AM__889__Second_Chance_Exception_C0000005.dmp
Type of Analysis Performed   Crash Analysis 
Machine Name   BV-DEV-SVR-4 
Operating System   Windows Server 2003 Service Pack 2 
Number Of Processors   2 
Process ID   3656 
Process Image   C:\php5\php.exe 
System Up-Time   9 day(s) 22:59:24 
Process Up-Time   00:00:00 


Thread 0 - System ID 2296
Entry point   php!mainCRTStartup 
Create time   26/04/2010 11:19:52 
Time spent in user mode   0 Days 0:0:0.93 
Time spent in kernel mode   0 Days 0:0:0.15 






Function     Arg 1     Arg 2     Arg 3   Source 
php5!zif_odbc_exec+31c     01b127e8     00000002     10022c5f    
php5!zif_odbc_fetch_array+10     00000001     01b127e8     00000000    
php5!execute+cdf     01b40080     01b10108     01b40080    
php5!execute+4c25     00c0ec28     00c0fed4     00c0fcbc    
php5!execute+1f0     01b10108     00c0fed4     00c0fcb8    
php5!zend_execute_scripts+be     00000008     00000000     00000003    
php5!php_execute_script+1e2     00c0fed4     0040642c     00000001    
php!main+a9a     00000004     003c4fc0     003c3730    
php!memcpy+160     00000000     00000000     7ffde000    
kernel32!BaseProcessStart+23     00402dda     00000000     00000000    




PHP5!ZIF_ODBC_EXEC+31CIn php__PID__3656__Date__04_26_2010__Time_11_19_52AM__889__Second_Chance_Exception_C0000005.dmp the assembly instruction at 
php5!zif_odbc_exec+31c in C:\php5\php5.dll from The PHP Group has caused an access violation exception (0xC0000005) when trying to read from memory 
location 0x00000028 on thread 0

Module Information 
Image Name: C:\php5\php5.dll   Symbol Type:  PDB 
Base address: 0x10000000   Time Stamp:  Wed Mar 03 20:45:15 2010  
Checksum: 0x00569e17   Comments:   
COM DLL: False   Company Name:  The PHP Group 
ISAPIExtension: False   File Description:  PHP Script Interpreter 
ISAPIFilter: False   File Version:  5.3.2 
Managed DLL: False   Internal Name:  PHP Script Interpreter 
VB DLL: False   Legal Copyright:  Copyright © 1997-2009 The PHP Group 
Loaded Image Name:  php5.dll   Legal Trademarks:  PHP 
Mapped Image Name:     Original filename:  php5.dll 
Module name:  php5   Private Build:   
Single Threaded:  False   Product Name:  PHP 
Module Size:  5.50 MBytes   Product Version:  5.3.2 
Symbol File Name:  C:\php5\debug\php5.pdb   Special Build:  &
 [2015-04-11 14:17 UTC] cmb@php.net
-Status: Open +Status: Feedback
 [2015-04-11 14:17 UTC] cmb@php.net
Does this issue still exist with recent PHP versions?
 [2015-04-13 18:16 UTC] RQuadling at GMail dot com
-Status: Feedback +Status: Open
 [2015-04-13 18:16 UTC] RQuadling at GMail dot com
WOW. Old bug. Sorry, but I'm not on Windows with MSSQL anymore. 

But if I was, I would probably use pdo_sqlsrv, I doubt this is an issue any more.
 [2020-10-05 15:35 UTC] cmb@php.net
-Status: Open +Status: Verified -Assigned To: +Assigned To: cmb
 [2020-10-05 15:35 UTC] cmb@php.net
> […], I doubt this is an issue any more.

Unfortunately, it is.  At least there should be no segfault.
Simple reproducer:

<?php
$conn = odbc_connect($dsn, $user, $pass);
$stmt = odbc_prepare($conn, "SELECT 1");
var_dump(odbc_execute($stmt));
var_dump(odbc_fetch_array($stmt));
var_dump(odbc_next_result($stmt));
var_dump(odbc_execute($stmt));
var_dump(odbc_fetch_array($stmt));
?>
 [2020-10-05 15:49 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=69ba81d183130b06d52ea1cd4574864ffae5dd84
Log: Fix #46050: odbc_next_result corrupts prepared resource
 [2020-10-05 15:49 UTC] cmb@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC