Bug #80783 [NEW]: PDO ODBC truncates BLOB records at every 256th byte

From: Date: Mon, 22 Feb 2021 10:12:03 +0000
Subject: Bug #80783 [NEW]: PDO ODBC truncates BLOB records at every 256th byte
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-232314@lists.php.net to get a copy of this message
From: horvath dot szabolcs at t-systems dot hu Operating system: Red Hat Enterprise Linux Server PHP version: 7.3.27 Package: PDO ODBC Bug Type: Bug Bug description:PDO ODBC truncates BLOB records at every 256th byte Description: ------------ Hi, We're using PHP 7.3.20 from Red Hat Software Collections. Although 7.3.27 is out there, I read thoroughly the changelog and haven't found similar bug between 7.3.20 and 7.3.27. There is a BLOB record in the database (Oracle 19c) which can be read with php-odbc and can't with php-pdo. We have a test case (see next chapter). The Oracle ODBC trace outputs for both PDO and ODBC version have been attached. It seems that ODBC is capable for reading the BLOB in a 25.744 bytes length chunk: [ODBC][26948][1613745870.667436][SQLGetData.c][237] Entry: Statement = 0x55e06001e950 Column Number = 1 Target Type = -2 SQL_C_BINARY Buffer Length = 131072 Target Value = 0x7f4fed496018 StrLen Or Ind = 0x7f4fed403388 [ODBC][26948][1613745870.668021][SQLGetData.c][545] Exit:[SQL_SUCCESS] Buffer = [BINARYDATA...] Strlen Or Ind = 0x7f4fed403388 -> 25744 While PDO reads it in a loop with 256 byte length chunks: [ODBC][32334][1613745953.051520][SQLGetData.c][545] Exit:[SQL_SUCCESS_WITH_INFO] Buffer = [UDEyRGJHdDdYdys0US9BNGxPaWpTbmJ2Q1lBSFFOczBLVUx0TnNTaHBCcjF6WEZ2dm9XZWt3VUtRSmJGVmJmRHBnWWg0MlhjckdTZjJBWWkvMG14VWNYT3htUm5BTy9m] Strlen Or Ind = 0x7f4fed4810d0 -> 25744 [ODBC][32334][1613745953.051771][SQLGetData.c][237] Entry: Statement = 0x55e05fe1fd30 Column Number = 1 Target Type = 1 SQL_CHAR Buffer Length = 256 Target Value = 0x7f4fed48f100 StrLen Or Ind = 0x7f4fed4810d0 [ODBC][32334][1613745953.051995][SQLGetData.c][545] Exit:[SQL_SUCCESS_WITH_INFO] Buffer = [Q3c3OGI2bnJycmVQMktmc2VNOWRmZ2c1ZVJDUUh0bFZNZCsyMWRjRHZnVTBrRjlCTE4wMWRKUTl4YjhkSDdoN3NBSTF0akdLT2ZvVGlTU3R6RnZJQmhSVGNGU3ZkRUxp] Strlen Or Ind = 0x7f4fed4810d0 -> 25488 [ODBC][32334][1613745953.052224][SQLGetData.c][237] Entry: Statement = 0x55e05fe1fd30 Column Number = 1 Target Type = 1 SQL_CHAR Buffer Length = 256 Target Value = 0x7f4fed48f100 StrLen Or Ind = 0x7f4fed4810d0 [ODBC][32334][1613745953.052459][SQLGetData.c][545] Exit:[SQL_SUCCESS_WITH_INFO] Buffer = [K0wzTHZabE1KejhOcHpIblVuYXJzTktXTmdvWEw0YlNPa2l0b0FTNkNvOFVtc1hzYnNXTGErVnVDbXVXUHdLTGZTWGtIUHR0aDVwZU1LRS9DNDlONVhKSjN2S21zOFl2] Strlen Or Ind = 0x7f4fed4810d0 -> 25232 I suspect at every 256 bytes length read there is one character truncated. Versions: rh-php73-php-odbc-7.3.20-1.el7.x86_64 rh-php73-php-pdo-7.3.20-1.el7.x86_64 https://github.com/php/php-src/blob/master/ext/pdo_odbc/odbc_stmt.c contains a lot of references for 256 bytes boundary. Here is a similar php pdo_odbc issue (https://github.com/microsoft/msphpsql/issues/1052) which matches, but it has not been solved (the caller moved on to pdo_sqlsrv instead of pdo_odbc) Thank you in advance. Best regards Szabolcs Horvath Test script: --------------- 1. ODBC version: $conn = odbc_connect("ORACLETEST", "user", "password"); $query = "SELECT pdf FROM PAYROLL WHERE USER_ID = 999 AND ROWNUM = 1 ORDER BY YEAR DESC, MONTH DESC"; if(!$conn) die("Connection failed"); if($result = odbc_exec($conn, $query)) { odbc_longreadlen($result, 131072); while(odbc_fetch_row($result)){ print strlen(odbc_result($result,1)); } } 2. PDO ODBC version: $pdo = new PDO("odbc:ORACLETEST", "user", "password" ); $stmt = $pdo->prepare('SELECT pdf FROM PAYROLL WHERE USER_ID = 999 AND ROWNUM = 1 ORDER BY YEAR DESC, MONTH DESC'); $stmt->bindColumn(1, $data, PDO::PARAM_LOB); $stmt->execute(); $stmt->fetch(PDO::FETCH_BOUND); print strlen($data); Expected result: ---------------- The actual data in the database is 25744 bytes long. Actual result: -------------- ODBC version returns with the length of 25744, and that's fine. PDO ODBC version returns with the length of 25644 byte, which is 100 bytes smaller than expected. -- Edit bug report at https://bugs.php.net/bug.php?id=80783&edit=1 -- Fix committed: https://bugs.php.net/fix.php?id=80783&r=fixed Fixed in release: https://bugs.php.net/fix.php?id=80783&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=80783&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=80783&r=needscript Try newer version: https://bugs.php.net/fix.php?id=80783&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=80783&r=support Expected behavior: https://bugs.php.net/fix.php?id=80783&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=80783&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=80783&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=80783&r=globals PHP version support discontinued: https://bugs.php.net/fix.php?id=80783&r=phptooold Daylight Savings: https://bugs.php.net/fix.php?id=80783&r=dst IIS Stability: https://bugs.php.net/fix.php?id=80783&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=80783&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=80783&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=80783&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=80783&r=mysqlcfg

« previous php.bugs (#232314) next »