Bug #60616 [NEW]: odbc_fetch_into returns junk data at end of multi-byte char fields

From: Date: Wed, 28 Dec 2011 11:57:14 +0000
Subject: Bug #60616 [NEW]: odbc_fetch_into returns junk data at end of multi-byte char fields
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-166116@lists.php.net to get a copy of this message
From: Operating system: Linux PHP version: 5.3.8 Package: ODBC related Bug Type: Bug Bug description:odbc_fetch_into returns junk data at end of multi-byte char fields Description: ------------ This relates to bug#25792, which has been marked Analyzed but does not seem to be fixed. When retrieving data from a char() field containing multi-byte characters using e.g. odbc_fetch_into(), if the number of bytes used exceeds the number of characters then junk data is returned at the end of the string. I have experience this with Postgres char columns when the database is created with e.g the EUC_CN character encoding(createdb -E EUC_CN). This encoding uses between 1 and 3 bytes per character. So a char(10) could need up to 30 bytes. The problem is in the odbc_bindcols function in ext/odbc/php_odbc.c SQLColAttributes is called with SQL_COLUMN_DISPLAY_SIZE but this indicates the maximum number of characters required not the number of bytes. This means the buffer allocated for the value may not be big enough result->values[i].value=(char)emalloc(displaysize+1); Later on in e.g. odbc_fetch_into Z_STRLEN_P(tmp) = result->values[i].vallen; Z_STRVAL_P(tmp) = estrndup(result->values[i].value,Z_STRLEN_P(tmp)); This can result in a vallen bigger that displaysize. But the ODBC driver will only fill in at most displaysize+1 bytes(including null terminator). This means character data is missed and junk bytes are returned instead. The same problem may exist in ext/pdo_odbc/odbc_stmt.c. Where rc = SQLColAttribute(S->stmt, colno+1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &displaysize); is called. But I have not tested this. The following fixes odbc_bindcols for the char(x) datatype. I believe 4 bytes is the maximum required for any character encoding. php_odbc.c:line 988 if (result->values[i].coltype == SQL_CHAR) { //If using a multibyte character encoding //number of bytes could be 4*SQL_COLUMN_DISPLAY_SIZE. //Without this workaround various functions //e.g. odbc_fetch_into will return data with a null after //diplaysize bytes and extra junk data at the end as //vallen can be bigger than displaysize. Tested using //PostgreSQL with EUC_CN encoding. displaysize*=4; } The fix may be needed for other data types as well as SQL_CHAR. -- Edit bug report at https://bugs.php.net/bug.php?id=60616&edit=1 -- Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=60616&r=trysnapshot54 Try a snapshot (PHP 5.3): https://bugs.php.net/fix.php?id=60616&r=trysnapshot53 Try a snapshot (trunk): https://bugs.php.net/fix.php?id=60616&r=trysnapshottrunk Fixed in SVN: https://bugs.php.net/fix.php?id=60616&r=fixed Fixed in SVN and need be documented: https://bugs.php.net/fix.php?id=60616&r=needdocs Fixed in release: https://bugs.php.net/fix.php?id=60616&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=60616&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=60616&r=needscript Try newer version: https://bugs.php.net/fix.php?id=60616&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=60616&r=support Expected behavior: https://bugs.php.net/fix.php?id=60616&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=60616&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=60616&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=60616&r=globals PHP 4 support discontinued: https://bugs.php.net/fix.php?id=60616&r=php4 Daylight Savings: https://bugs.php.net/fix.php?id=60616&r=dst IIS Stability: https://bugs.php.net/fix.php?id=60616&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=60616&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=60616&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=60616&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=60616&r=mysqlcfg

« previous php.bugs (#166116) next »