ID: 33965
Updated by: [EMAIL PROTECTED]
-Summary: NULL valued output parameters from stored procedures
contain corrupt data
Reported By: paul dot robinson at groupbc dot com
-Status: Open
+Status: Assigned
Bug Type: MSSQL related
Operating System: Linux (RHEL 4)
-PHP Version: 5.0.4
+PHP Version: 5CVS-2005-08-06
-Assigned To:
+Assigned To: fmk
New Comment:
Frank, can you check this out?
Previous Comments:
------------------------------------------------------------------------
[2005-08-05 16:57:19] paul dot robinson at groupbc dot com
Patch against php_mssql.c CVS version 1.149 can be found here:
http://cobweb.businesscollaborator.com/pdr/33965.patch
Rationale behind the patch was discussed here:
http://lists.ibiblio.org/pipermail/freetds/2005q3/018851.html
This has been verified to work with FreeTDS releases _after_ 0.63.
Without this patch output parameters that should be null will simply
read random data.
------------------------------------------------------------------------
[2005-08-02 19:12:53] [EMAIL PROTECTED]
Provide patches in unified diff format (diff -u) and against PHP CVS
HEAD (we're not likely to release any 5.0.x versions anymore). Put the
diffs somewhere were people can download it and put the URLs here.
------------------------------------------------------------------------
[2005-08-02 18:50:33] paul dot robinson at groupbc dot com
Patches suggested are against Snapshot:
php5-STABLE-200508021038.tar.gz
Although I haven't actually built an example using that snapshot today
I have looked at the code which since it is unchanged would seem to
exhibit the same problem.
------------------------------------------------------------------------
[2005-08-02 18:34:21] [EMAIL PROTECTED]
Please try using this CVS snapshot:
http://snaps.php.net/php5-latest.tar.gz
For Windows:
http://snaps.php.net/win32/php5-win32-latest.zip
------------------------------------------------------------------------
[2005-08-02 14:01:38] paul dot robinson at groupbc dot com
Description:
------------
MS SQL Server 2000, FreeTDS 0.63
Output parameters from a stored procedure call contain corrupt data
when the result should be NULL. Its particularly noticable for variable
length strings as output looks as though it just reads from a random
pointer until it find a \0 !
No test is done on whether the output is NULL or not.
Diff below shows proposed change to fix this.
NOTE: This calls a function dbretisnull that is not currently
implemented in the FreeTDS package but has been submitted as a proposed
change.
19c19
< /* $Id: php_mssql.c,v 1.137.2.9 2005/04/12 17:46:06 fmk Exp $ */
---
> /* $Id: php_mssql.c,v 1.137.2.8 2005/02/25 23:25:33 fmk Exp $ */
324,326d323
< #ifndef HAVE_FREETDS
< dbwinexit();
< #else
328d324
< #endif
978c974
< int i, num_rets, type;
---
> int i, num_rets, type, is_null;
992,1019c988,1022
< switch (type) {
< case SQLBIT:
< case SQLINT1:
< case SQLINT2:
< case SQLINT4:
<
convert_to_long_ex(&bind->zval);
< /* FIXME this
works only on little endian machine !!! */
<
Z_LVAL_P(bind->zval) = *((int *)(dbretdata(mssql_ptr->link,i)));
< break;
<
< case SQLFLT4:
< case SQLFLT8:
< case SQLFLTN:
< case SQLMONEY4:
< case SQLMONEY:
< case SQLMONEYN:
<
convert_to_double_ex(&bind->zval);
<
Z_DVAL_P(bind->zval) = *((double *)(dbretdata(mssql_ptr->link,i)));
< break;
<
< case SQLCHAR:
< case SQLVARCHAR:
< case SQLTEXT:
<
convert_to_string_ex(&bind->zval);
<
Z_STRLEN_P(bind->zval) = dbretlen(mssql_ptr->link,i);
<
Z_STRVAL_P(bind->zval) =
estrndup(dbretdata(mssql_ptr->link,i),Z_STRLEN_P(bind->zval));
< break;
< /* TODO binary */
---
> /* Test column value for null
flag and set value as required */
> is_null =
dbretisnull(mssql_ptr->link, i);
> if (is_null) {
> ZVAL_NULL(bind->zval);
> }
> else {
> switch (type) {
> case SQLBIT:
> case SQLINT1:
> case SQLINT2:
> case SQLINT4:
>
convert_to_long_ex(&bind->zval);
> /*
FIXME this works only on little endian machine !!! */
>
Z_LVAL_P(bind->zval) = *((int *)(dbretdata(mssql_ptr->link,i)));
> break;
>
> case SQLFLT4:
> case SQLFLT8:
> case SQLFLTN:
> case
SQLMONEY4:
> case SQLMONEY:
> case
SQLMONEYN:
>
convert_to_double_ex(&bind->zval);
>
Z_DVAL_P(bind->zval) = *((double *)(dbretdata(mssql_ptr->link,i)));
> break;
>
> case SQLCHAR:
> case
SQLVARCHAR:
> case SQLTEXT:
>
convert_to_string_ex(&bind->zval);
>
Z_STRLEN_P(bind->zval) = dbretlen(mssql_ptr->link,i);
>
Z_STRVAL_P(bind->zval) =
estrndup(dbretdata(mssql_ptr->link,i),Z_STRLEN_P(bind->zval));
> break;
> /* TODO binary
*/
> }
Reproduce code:
---------------
function if_null($out) {
if(is_null($out)) { return 'null'; }
else { return $out; }
}
$int0out =-1;
$varchar0out = -1;
$conn = mssql_connect (DBSERVER, USER, PASS);
mssql_select_db(DBDATABASE, $conn)
$query = mssql_init('usp_output_test', $conn);
mssql_bind($query, "@int0out", $int0out, SQLINT4, true, false);
mssql_bind($query, "@varchar0out", $varchar0out, SQLVARCHAR, true,
false, 10);
$myset = mssql_execute($query);
if($line = mssql_fetch_array($myset)) {
print "there was a result set!";
}
else {
print "no resultset";
}
print if_null($int0out). " --int0out output</br>";
print if_null($varchar0out). " --varchar0out output</br>";
Expected result:
----------------
null --int0out output
null --varchar0out output
Actual result:
--------------
null --int0out output
82$┤,╝d♥n╓ --varchar0out output
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=33965&edit=1