|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2005-08-02 13:39 UTC] paul dot robinson at groupbc dot com
 Description:
------------
Using FreeTDS 0.63 (latest stable release), calling mssql_bind can fail due to the restrictions placed on parameters by the dbrpcparam function from FreeTDS.
One specific example is an input parameter must have maxlen==-1. With the code as is in PHP 5.0.4 a NULL valued variable length type input parameter will always have maxlen==0 thereby always failing.
Diff below shows changes to ext/mssql/php_mssql.c that address this parameter mismatch.
2025,2026c2025,2029
<                       maxlen=0;
<                       datalen=0;
---
>                       datalen = 0;
>                       if (is_output)
>                               maxlen = -1;
>                       else
>                               maxlen = -1;
2030d2032
<                       datalen=Z_STRLEN_PP(var);
2031a2034,2046
> 
>                       if (is_output) {
>                         if ((maxlen > 0 ) && (maxlen < 256))
>                               datalen = maxlen;
>                         else {
>                               maxlen = 255;
>                               datalen = 255;
>                         }
>                       }
>                       else {
>                         maxlen = -1;
>                         datalen=Z_STRLEN_PP(var);
>                       }
Reproduce code:
---------------
mssql_bind($query, "@varchar1", $varchar1, SQLVARCHAR);
or
mssql_bind($query, "@varchar1", $varchar1, SQLVARCHAR, false, true, 57);
Expected result:
----------------
Sucessfully bind input variable.
Actual result:
--------------
"Unable to set parameter"
i.e. FAIL is returned by the call to dbrpcparam in PHP_FUNCTION(mssql_bind).
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 08:00:01 2025 UTC | 
Fixed in CVS. Note however that if you call mssql_bind passing 7 parameters with maxlen = XXX and is_output = false you call dbrpcparam with status == 0 and maxlen = XXX, this is not correct, you should pass maxlen == -1 or maxlen == 0 (for NULL variable types... bad specifications but is what MS specify). Change these lines case 7: { zval **yyis_output, **yyis_null, **yymaxlen; if (zend_get_parameters_ex(7, &stmt, ¶m_name, &var, &yytype, &yyis_output, &yyis_null, &yymaxlen)==FAILURE){ RETURN_FALSE; } convert_to_long_ex(yytype); convert_to_long_ex(yyis_output); convert_to_long_ex(yyis_null); convert_to_long_ex(yymaxlen); type=Z_LVAL_PP(yytype); is_output=Z_LVAL_PP(yyis_output); is_null=Z_LVAL_PP(yyis_null); maxlen=Z_LVAL_PP(yymaxlen); } break; with case 7: { zval **yyis_output, **yyis_null, **yymaxlen; if (zend_get_parameters_ex(7, &stmt, ¶m_name, &var, &yytype, &yyis_output, &yyis_null, &yymaxlen)==FAILURE) { RETURN_FALSE; } convert_to_long_ex(yytype); convert_to_long_ex(yyis_output); convert_to_long_ex(yyis_null); convert_to_long_ex(yymaxlen); type=Z_LVAL_PP(yytype); is_output=Z_LVAL_PP(yyis_output); is_null=Z_LVAL_PP(yyis_null); maxlen=Z_LVAL_PP(yymaxlen); if (!is_output) maxlen = -1; } break; Or if (is_output) { status=DBRPCRETURN; } to if (is_output) { status=DBRPCRETURN; } else { maxlen = -1; } (mssql_bind function) freddy77I've tried this patch to php_mssql.c with good results (so far): *** 2016,2021 **** --- 2016,2033 ---- mssql_ptr=statement->link; /* modify datalen and maxlen according to dbrpcparam documentation */ + + /* handle maxlen for input parameters */ + + if (!is_output) { + if (is_null) { + maxlen=0; + } + else { + maxlen=-1; + } + } + if ( (type==SQLVARCHAR) || (type==SQLCHAR) || (type==SQLTEXT) ) { /* variable-length type */ if (is_null) { maxlen=0;