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
 [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

Add a Patch

Pull Requests

Add a Pull Request

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: Fri Apr 19 23:01:28 2024 UTC