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

Reply via email to