|
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 GroupAll rights reserved. |
Last updated: Wed Oct 29 10: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;