ID:               33965
 Updated by:       [EMAIL PROTECTED]
 Reported By:      paul dot robinson at groupbc dot com
-Status:           Open
+Status:           Feedback
 Bug Type:         MSSQL related
 Operating System: Linux (RHEL 4)
 PHP Version:      5.0.4
 New Comment:

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.






Previous Comments:
------------------------------------------------------------------------

[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$&#9508;,&#9565;d&#9829;n&#9555; --varchar0out output


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=33965&edit=1

Reply via email to