#33965 [NEW]: NULL valued output parameters from stored procedures contain corrupt data
| From: | paul dot robinson at groupbc dot com | Date: | Tue, 02 Aug 2005 12:01:40 +0000 |
| Subject: | #33965 [NEW]: NULL valued output parameters from stored procedures contain corrupt data | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-82814@lists.php.net to get a copy of this message | ||
From: paul dot robinson at groupbc dot com
Operating system: Linux (RHEL 4)
PHP version: 5.0.4
PHP Bug Type: MSSQL related
Bug description: NULL valued output parameters from stored procedures contain corrupt data
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 bug report at http://bugs.php.net/?id=33965&edit=1
--
Try a CVS snapshot (php4): http://bugs.php.net/fix.php?id=33965&r=trysnapshot4
Try a CVS snapshot (php5.0): http://bugs.php.net/fix.php?id=33965&r=trysnapshot50
Try a CVS snapshot (php5.1): http://bugs.php.net/fix.php?id=33965&r=trysnapshot51
Fixed in CVS: http://bugs.php.net/fix.php?id=33965&r=fixedcvs
Fixed in release: http://bugs.php.net/fix.php?id=33965&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=33965&r=needtrace
Need Reproduce Script: http://bugs.php.net/fix.php?id=33965&r=needscript
Try newer version: http://bugs.php.net/fix.php?id=33965&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=33965&r=support
Expected behavior: http://bugs.php.net/fix.php?id=33965&r=notwrong
Not enough info: http://bugs.php.net/fix.php?id=33965&r=notenoughinfo
Submitted twice: http://bugs.php.net/fix.php?id=33965&r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=33965&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=33965&r=php3
Daylight Savings: http://bugs.php.net/fix.php?id=33965&r=dst
IIS Stability: http://bugs.php.net/fix.php?id=33965&r=isapi
Install GNU Sed: http://bugs.php.net/fix.php?id=33965&r=gnused
Floating point limitations: http://bugs.php.net/fix.php?id=33965&r=float
No Zend Extensions: http://bugs.php.net/fix.php?id=33965&r=nozend
MySQL Configuration Error: http://bugs.php.net/fix.php?id=33965&r=mysqlcfg