Bug #47133 [Com]: php-odbc SQLBindCol() not used correctly
| From: | crypteo at gmail dot com | Date: | Mon, 05 Mar 2012 09:13:45 +0000 |
| Subject: | Bug #47133 [Com]: php-odbc SQLBindCol() not used correctly | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-168134@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=47133&edit=1
ID: 47133
Comment by: crypteo at gmail dot com
Reported by: marquis at us dot ibm dot com
Summary: php-odbc SQLBindCol() not used correctly
Status: Open
Type: Bug
Package: ODBC related
Operating System: Fedora 9
PHP Version: 5.2.8
Block user comment: N
Private report: N
New Comment:
This is still happening with php 5.3.10
Previous Comments:
------------------------------------------------------------------------
[2009-01-17 00:13:11] marquis at us dot ibm dot com
Description:
------------
PHP applications that use the iSeries Access for Linux ODBC driver to SELECT CHAR data containing
characters outside the invariant character set (for example: "ü"), and using a UTF-8
locale, may receive extra garbage data at the end of the character string.
This is caused by PHP passing an insufficient target length on the call to SQLBindCol(). PHP is
setting the incorrect buffer length by using SQLColAttributes to return the SQL_COLUMN_DISPLAY_SIZE.
I have seen this behavior on PHP 5.1 and 5.2.6-2
This problem also exists in PHP for Windows.
The iSeries Access for Linux ODBC driver correctly returns error message :
CWB0111 - A buffer passed to a system call is too small to hold return data
However, the ODBC driver will be changed to not return the extra garbage data at the end of the CHAR
string when using a connection string keyword option.
PHP applications could then ignore the CWB0111 error message.
For PHP applications using the UTF8 locale to use this workaround and prevent the extra garbage
data, the odbc connection must pass in the following connection string keyword:
DEBUG = 65536
Additional options:
PHP does not calculate all buffer lengths using SQL_COLUMN_DISPLAY SIZE, so, PHP developers could
use other SQL column types such as:
SQL_BINARY, SQL_VARBINARY, SQL_LONGVARBINARY or SQL_LONGVARCHAR. No binding occurs with those data
types and SQLGetData() is used to retrieve the value.
For long data it may be neccessary to call PHP ODBC API odbc_longread()
(http://us3.php.net/odbc_longreadlen) , because that is the length to be used for the buffer. If
less data is available, PHP shrinks the buffer, but if more data is available, truncation will
occur.
Ref IBM APAR SE33393
http://www-912.ibm.com/n_dir/nas4apar.nsf/ALLAPARS/SE33393
The ideal solution would be for PHP to use the correct buffer length on the call to SQLBindCol().
Reproduce code:
---------------
#!/usr/bin/php
<?
//setlocale(LC_ALL, 'de_DE');
$link = odbc_connect("MySystem","MyUserID","MyPasswd");
$result = odbc_exec($link,"select * from MySchema.MyTable");
$count = 0;
while ($val= odbc_fetch_array($result)) {
var_dump($val);
$count++;
}
odbc_close($link);
print "locale is :/n";
system('locale');
?>
Expected result:
----------------
Just return the CHAR string without extra data at the end.
For example:
array(1) {
["AFIELD"]=>
string(6) "ü "
}
Actual result:
--------------
array(1) {
["AFIELD"]=>
string(40) "ü <bunch of garbage here as well as NULLs>"
}
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=47133&edit=1