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

From: Date: Mon, 22 Feb 2021 10:15:59 +0000
Subject: Bug #80783 [Com]: PDO ODBC truncates BLOB records at every 256th byte
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-232315@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80783&edit=1 ID: 80783 Comment by: horvath dot szabolcs at t-systems dot hu Reported by: horvath dot szabolcs at t-systems dot hu Summary: PDO ODBC truncates BLOB records at every 256th byte Status: Open Type: Bug Package: PDO ODBC Operating System: Red Hat Enterprise Linux Server PHP Version: 7.3.27 Block user comment: N Private report: N New Comment: Actual php-odbc trace: [ODBC][26948][1613745870.512493][SQLConnect.c][3721] Entry: Connection = 0x55e05fd3fb90 Server Name = [ORACLETEST][length = 11 (SQL_NTS)] User Name = [user][length = 11 (SQL_NTS)] Authentication = [********][length = 8 (SQL_NTS)] UNICODE Using encoding ASCII 'UTF-8' and UNICODE 'UTF16LE' [ODBC][26948][1613745870.647085][SQLConnect.c][4299] Exit:[SQL_SUCCESS] [ODBC][26948][1613745870.647748][SQLAllocHandle.c][540] Entry: Handle Type = 3 Input Handle = 0x55e05fd3fb90 [ODBC][26948][1613745870.648513][SQLAllocHandle.c][1085] Exit:[SQL_SUCCESS] Output Handle = 0x55e06001e950 [ODBC][26948][1613745870.649134][SQLGetInfo.c][236] Entry: Connection = 0x55e05fd3fb90 Info Type = SQL_FETCH_DIRECTION (8) Info Value = 0x7fff66837184 Buffer Length = 4 StrLen = (nil) [ODBC][26948][1613745870.649701][SQLSetStmtOption.c][197] Entry: Statement = 0x55e06001e950 Option = SQL_ATTR_CURSOR_TYPE Value = 3 [ODBC][26948][1613745870.650504][SQLSetStmtOption.c][477] Exit:[SQL_SUCCESS] [ODBC][26948][1613745870.650884][SQLExecDirect.c][240] Entry: Statement = 0x55e06001e950 SQL = [SELECT pdf FROM PAYROLL WHERE USER_ID = 999 AND ROWNUM = 1 ORDER BY YEAR DESC, MONTH DESC][length = 89 (SQL_NTS)] [ODBC][26948][1613745870.657670][SQLExecDirect.c][521] Exit:[SQL_SUCCESS] [ODBC][26948][1613745870.658258][SQLNumResultCols.c][156] Entry: Statement = 0x55e06001e950 Column Count = 0x7f4fed402358 [ODBC][26948][1613745870.658848][SQLNumResultCols.c][251] Exit:[SQL_SUCCESS] Count = 0x7f4fed402358 -> 1 [ODBC][26948][1613745870.659390][SQLColAttribute.c][294] Entry: Statement = 0x55e06001e950 Column Number = 1 Field Identifier = SQL_DESC_NAME Character Attr = 0x7f4fed403280 Buffer Length = 256 String Length = 0x7fff66837092 Numeric Attribute = (nil) [ODBC][26948][1613745870.659942][SQLColAttribute.c][709] Exit:[SQL_SUCCESS] [ODBC][26948][1613745870.660461][SQLColAttribute.c][294] Entry: Statement = 0x55e06001e950 Column Number = 1 Field Identifier = SQL_DESC_CONCISE_TYPE Character Attr = (nil) Buffer Length = 0 String Length = (nil) Numeric Attribute = 0x7f4fed403390 [ODBC][26948][1613745870.660998][SQLColAttribute.c][709] Exit:[SQL_SUCCESS] [ODBC][26948][1613745870.661602][SQLExtendedFetch.c][166] Entry: Statement = 0x55e06001e950 Fetch Type = 1 Row = 1 PcRow = 0x7fff66837190 Row Status = 0x7fff66837170 [ODBC][26948][1613745870.666906][SQLExtendedFetch.c][339] Exit:[SQL_SUCCESS] [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 [ODBC][26948][1613745870.668576][SQLExtendedFetch.c][166] Entry: Statement = 0x55e06001e950 Fetch Type = 1 Row = 1 PcRow = 0x7fff66837190 Row Status = 0x7fff66837170 [ODBC][26948][1613745870.669176][SQLExtendedFetch.c][339] Exit:[SQL_NO_DATA] [ODBC][26948][1613745870.669937][SQLFreeStmt.c][144] Entry: Statement = 0x55e06001e950 Option = 1 [ODBC][26948][1613745870.670454][SQLFreeHandle.c][387] Entry: Handle Type = 3 Input Handle = 0x55e06001e950 [ODBC][26948][1613745870.671122][SQLFreeHandle.c][490] Exit:[SQL_SUCCESS] [ODBC][26948][1613745870.671663][SQLDisconnect.c][208] Entry: Connection = 0x55e05fd3fb90 [ODBC][26948][1613745871.630195][SQLDisconnect.c][379] Exit:[SQL_SUCCESS] [ODBC][26948][1613745871.630471][SQLFreeHandle.c][290] Entry: Handle Type = 2 Input Handle = 0x55e05fd3fb90 [ODBC][26948][1613745871.630712][SQLFreeHandle.c][339] Exit:[SQL_SUCCESS] [ODBC][26948][1613745871.630939][SQLFreeHandle.c][220] Entry: Handle Type = 1 Input Handle = 0x55e05fd305c0 Previous Comments: ------------------------------------------------------------------------ [2021-02-22 10:12:03] horvath dot szabolcs at t-systems dot hu 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 this bug report at https://bugs.php.net/bug.php?id=80783&edit=1

« previous php.bugs (#232315) next »