Edit report at https://bugs.php.net/bug.php?id=69354&edit=1
ID: 69354
Updated by: ab@php.net
Reported by: php at mdjnet dot dk
Summary: Incorrect use of SQLColAttributes with ODBC 3.0
-Status: Assigned
+Status: Feedback
Type: Bug
Package: ODBC related
Operating System: All
PHP Version: 5.6.7
Assigned To: ab
Block user comment: N
Private report: N
New Comment:
Please check this snapshot http://windows.php.net/downloads/snaps/master/rf265928/
. I've integrated appropriate usage SQLColAttribute usage for ODBC 3.x and a couple of other
compliance fixes.
With your snippet - I couldn't reproduce the behavior you describe with SQL Server or mdb
driver. For this reason I've put the patches into master only, maybe yet. Maybe you should give
me an exact CREATE TABLE and data.
The idea of using the ODBC 3.x APIs is actually good, I've also seen that there are many other
APIs from 2.x used in ext/odbc. However the docs state some high compatibilty grade (with exception
of some edge cases), so maybe it's also plausible to fix issues as they show up.
Thanks.
Previous Comments:
------------------------------------------------------------------------
[2015-04-02 14:07:36] php at mdjnet dot dk
I am using a proprietary ODBC driver based on http://syware.com/products/odbc_driver_kit.php.
I just tried to set up a scenario using Microsoft Access Driver (*.mdb), but it does allow to call
SQLColAttributes with SQL_DESC_OCTET_LENGTH, so it did not have the problem.
A simple script showing the problem:
<html><body>
<?php $db = odbc_connect('TEST','','');
$res = odbc_exec($db,"select TNAME from Table1");
if ($res)
if (odbc_fetch_row($res))
{
$tname = odbc_result($res,'tname');
print("tname = $tname\n");
} ?>
</body></html>
using a simple mdb file with a table, Table1, containing a column, TNAME. The bug would cause the
content of tname to be truncated somewhere - but I suppose you do need an ODBC driver NOT allowing
SQLColAttributes with SQL_DESC_OCTET_LENGTH in order to see it. I *could* write a special edition of
my odbc driver, displaying just this behaviour? I do believe that https://msdn.microsoft.com/en-us/library/ms711003
and https://msdn.microsoft.com/en-us/library/ms713558
documents the problem, but I guess we should be careful not to patch up php just to fit a special
built odbc driver. Can't point you to any other driver triggering this problem though...
------------------------------------------------------------------------
[2015-04-02 12:02:14] ab@php.net
Hi,
please supply a code snippet illustrating the broken behavior. Are you using the ADS driver, or
which exactly?
Thanks.
------------------------------------------------------------------------
[2015-04-02 08:35:28] php at mdjnet dot dk
Description:
------------
Since php was changed to odbc 3.0 (#68964), an old hidden bug has surfaced. This bug is related to
both #68350 "SQL_DESC_OCTET_LENGTH not supported by ADS ODBC driver" and #68014
"Result data values can be truncated because of incorrect column display sizes".
In odbc 3.0, SQLColAttributes is deprecated, instead SQLColAttribute should be used, which in turn
supports SQL_DESC_OCTET_LENGTH, introduced with odbc 3.0.
The bug is in ext/odbc/php_odbc.c, the function odbc_bindcols, in the middle of the big switch. With
ODBCVER set to 0x0300 as of php 5.6.7, the extra cases of SQL_WCHAR and SQL_WVARCHAR come into
effect, setting colfieldid to SQL_DESC_OCTET_LENGTH also for SQL_CHAR and SQL_VARCHAR due to a
rather suspiscious fall-through strategy, that worked well for ODBCVER < 0x0300. However, not all
odbc drivers allow for SQLColAttributes to be called with SQL_DESC_OCTET_LENGTH.
If SQLColAttributes fails, the effect is that strings lifted from subsequent calls to odbc_result
become truncated, probably because of uninitialized variables, as the code doesn't even look at
the return value of SQLColAttributes (same effect as in #68014, which appears to be fixed judging
from looking at the code).
The correct fix would be to call SQLColAttribute instead of SQLColAttributes, if ODBCVER >=
0x0300, and to actually check the return value before using the result of the call (displaysize).
I have never figured out how to build my own php, so I have not tried to fix it directly in
php_odbc.c, but I have tried to fix my odbc driver to support SQL_DESC_OCTET_LENGTH in
SQLColAttributes, and that does indeed fix the problem.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=69354&edit=1