php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #28512 Mssql.c runtime error
Submitted: 2004-05-25 00:53 UTC Modified: 2004-06-30 21:47 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:1 (50.0%)
From: barry at hpfm dot com dot au Assigned:
Status: Closed Package: *Web Server problem
PHP Version: 4.3.5 OS: Redhat 9.0
Private report: No CVE-ID: None
 [2004-05-25 00:53 UTC] barry at hpfm dot com dot au
Description:
------------
I am developing an application that runs php on Rh9.0,Apache1.3 that accesses data residing on a Windows SBS server running SQLSERVER.  

I am getting huge apache error_log files (see attached sample) because of a memory leak in msssql.c.

The application runs quite slowly and really hammers the apache server.

The application is using PEAR DB, DBO.

Occassionally the $dbo->find() will not return anything at all.

Reproduce code:
---------------
<?php
require_once "config.php";
require_once "DataObjects/Person.php";
require_once "DataObjects/Members.php";
$person = new DataObject_Person;
$member = new DataObject_Members;
echo "Starting DB Tests: find all CPl members<br>";
$member->debugLevel(0);
echo "Issue find request<br>";	
$transfers=$member->find();

echo $transfers." CPL folk to translate<br>";
while ( ( $member->fetch() ) )
	{
	echo "<pre>";
	var_dump($member->toArray());
	echo "</pre>";
	}


?>

Actual result:
--------------
---------------------------------------
[Tue May 25 08:47:49 2004]  Script:  '/www/sites/slsa/SLSA_Members/include/DBTes
ts01.php'
---------------------------------------
/downloads/php4.3/php4.3.5/php-4.3.5/ext/mssql/php_mssql.c(191) : Block 0x083839
00 status:
/downloads/php4.3/php4.3.5/php-4.3.5/Zend/zend_variables.c(44) : Actual location
 (location was relayed)
Beginning:      OK (allocated on /downloads/php4.3/php4.3.5/php-4.3.5/ext/mssql/
php_mssql.c:847, 19 bytes)
      End:      Overflown (magic=0x2A8FCC00 instead of 0x2A8FCC84)
                1 byte(s) overflown
---------------------------------------


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-05-25 23:28 UTC] fmk@php.net
Can you please try to create a sample that uses the native function calls directly. That would make debugging easier for me.
 [2004-06-02 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".
 [2004-06-23 23:22 UTC] barry at hpfm dot com dot au
Problem still exists  - I'll try to get more details on the exact sequence of calls though the only real notive we get is a radical reduction in the performance of the queries and the associated <path_to_logs>/error_log file produced by Apache.
 [2004-06-30 16:34 UTC] daniel dot beet at accuratesoftware dot com
We are experiencing a similar crash, when values in 
decimal or numeric columns are larger than certain values.

Reproduced on MS SQL 2000 on Windows 2000 Server, with 
Apache 1.3.27 as webserver or CLI php exe on Win XP.

Create table with data:

CREATE TABLE [dbo].[test] (
	[test_decimal] [decimal](23, 6) NULL ,
	[test_numeric] [numeric](23, 6) NULL 
) ON [PRIMARY]
GO

INSERT INTO test (test_decimal, test_numeric) 
VALUES (99999999999999999.999999, 99999999999999999.999999)
GO

Run following PHP script:
<?php

$conn = mssql_connect('yourserver', 'you', 'password');
echo "Connection OK<br />\n";

mssql_select_db('yourdatabase', $conn);
echo "DB selected OK<br />\n";

$result = mssql_query('select test_decimal, test_numeric from test', $conn);
echo "Query OK<br />\n";

$array[] = mssql_fetch_field($result, 0);
$array[] = mssql_field_name($result, 0);
$array[] = mssql_field_type($result, 0);
$array[] = mssql_field_length($result, 0);
$array[] = mssql_fetch_assoc($result);
echo "Results fetched OK<br />\n";

echo '<pre>';
var_export($array);
echo '</pre>';

mssql_close($conn);

?>

I have solved the issue with the following diff of changes to php_mssql.c:

841a842
> 		case SQLDECIMAL:
850,852c851,866
< 					if (column_type == SQLDATETIM4) res_length += 14;
< 					if (column_type == SQLDATETIME) res_length += 10;
< 			
---
> 					switch (column_type) {
> 						case SQLDATETIM4 :
> 							res_length += 14;
> 							break;
> 						case SQLDATETIME :
> 							res_length += 10;
> 							break;
> 						case SQLMONEY :
> 						case SQLMONEY4 :
> 						case SQLMONEYN :
> 						case SQLDECIMAL :
> 						case SQLNUMERIC :
> 							res_length += 5;
> 							break;
> 					}
> 
919a934,935
> 				case SQLDECIMAL :
> 				case SQLNUMERIC :


The buffer res_buf was beeing allocated to small (20 for above columns, when 24 is required)

Hope that this helps, as it is critical for us!
 [2004-06-30 16:39 UTC] daniel dot beet at accuratesoftware dot com
Sorry, PHP versions 4.3.7 and 4.3.4

Thanks,

Dan
 [2004-06-30 21:47 UTC] fmk@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.


 [2004-07-07 09:59 UTC] daniel dot beet at accuratesoftware dot com
I have since found that my patch did not fully fix the bug. Sorry to mess you about, but here is a better patch that will work for DECIMAL and NUMERIC columns up to the maximum allowed precision (38).

I have also removed the extra code in the first patch for SQLMONEY types, as they were catered for further up in the function.

Also I noticed that the function mssql_field_type() returns Decimal types as "real", where as Numeric types are returned as "numeric", since they are synonymous, I thought that this was not right, and that both should be called "numeric"?

Patch against: php_mssql.c CVS version 1.86.2.34:

841d840
< 		case SQLNUMERIC:
857,859d855
< 						case SQLMONEY :
< 						case SQLMONEY4 :
< 						case SQLMONEYN :
862c858
< 							res_length += 5;
---
> 							res_length = 40;
932a929,930
> 					res_length = 23;
> 					break;
935c933
< 					res_length += 5;
---
> 					res_length = 40;
1070a1069,1071
> 			case SQLMONEY4:
> 			case SQLMONEY:
> 			case SQLMONEYN:
1505d1505
< 		case SQLDECIMAL:
1517a1518
> 		case SQLDECIMAL:
 [2004-07-16 00:27 UTC] brian at groundspring dot org
I have encountered a related bug in php5.  If you select a datetime field from an MSSQL table without specifying a format, it assumes a default field length of 19.

On our setup, the datetime is returned in a format of length 24 (eg: Thu Jul 15 15:26:00 2004).  I've gotten around this by patching res_length to be arbitrarily large (+= 19 instead of 14 or 10), but there must be a cleaner solution out there.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 09:01:30 2024 UTC