[php-src] Issue #24474: [pdo_odbc] Buffer overflow / CWB0111 on SQL_BIT columns with IBM i Access ODBC Driver

From: Date: Wed, 21 Oct 2026 10:07:52 +0000
Subject: [php-src] Issue #24474: [pdo_odbc] Buffer overflow / CWB0111 on SQL_BIT columns with IBM i Access ODBC Driver
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-253051@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/24474 Author: boivinj ### Description ### Description When fetching rows containing native BOOLEAN columns from IBM Db2 for i (IBM i 7.5+) using pdo_odbc with the official IBM i Access ODBC Driver (libcwbodbc.so), SQLFetchScroll throws a buffer overflow error: ```text SQLSTATE[22018]: Invalid character value for cast specification: 30200 [IBM][System i Access ODBC Driver]Column X: CWB0111 - A buffer passed to a system call is too small to hold return data (SQLFetchScroll[30200] at ext/pdo_odbc/odbc_stmt.c:624) ``` ### Root Cause Analysis In ext/pdo_odbc/odbc_stmt.c inside odbc_stmt_describe(): 1. pdo_odbc queries SQL_DESC_DISPLAY_SIZE via SQLColAttribute: ```c rc = SQLColAttribute(S->stmt, colno+1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &displaysize); colsize = displaysize; ``` 2. For an IBM i BOOLEAN column (ODBC type SQL_BIT / -7), the IBM driver reports a display size of 1. 3. Because colsize < LONG_COLUMN_BUFFER_SIZE (1 < 256), pdo_odbc allocates a 2-byte fixed buffer (emalloc(colsize + 1)): ```c S->cols[colno].data = emalloc(colsize+1); // allocates 2 bytes rc = SQLBindCol(S->stmt, colno+1, S->cols[colno].is_unicode ? SQL_C_BINARY : SQL_C_CHAR, S->cols[colno].data, S->cols[colno].datalen+1, &S->cols[colno].fetched_len); ``` 4. While the ODBC specification states that SQL_BIT converted to SQL_C_CHAR should return "0" or "1", the IBM i Access ODBC driver (libcwbodbc.so) formats boolean values as "TRUE" (5 bytes with null terminator) or "FALSE" (6 bytes with null terminator). 5. During SQLFetchScroll, writing "FALSE\0" (6 bytes) into the 2-byte buffer triggers the driver's CWB0111 buffer overflow error. ### PHP Version PHP 8.3 / 8.4 / 8.5 ### Operating System & Environment - **OS:** Linux (Debian 12 / Ubuntu 24.04 / Docker) - **ODBC Manager:** unixODBC 2.3.12 - **ODBC Driver:** IBM i Access Client Solutions (ibm-iaccess 1.1.0.29-1.0 / libcwbodbc.so) - **Database:** IBM Db2 for i (IBM i 7.5+) ### Steps to Reproduce 1. Connect to an IBM i 7.5+ system with pdo_odbc. 2. Create a table with a native BOOLEAN column: ```sql CREATE TABLE test_bool (id INT, is_active BOOLEAN); INSERT INTO test_bool VALUES (1, FALSE); ``` 3. Run a query through PDO: ```php $pdo = new PDO('odbc:DRIVER={IBM i Access ODBC Driver};SYSTEM=...;', $user, $password); $stmt = $pdo->query('SELECT is_active FROM test_bool'); $rows = $stmt->fetchAll(); // Throws CWB0111 ``` ### Expected Result The row should be fetched without errors (returning 'FALSE', '0' or boolean equivalent). ### Actual Result ```text Fatal error: Uncaught PDOException: SQLSTATE[22018]: Invalid character value for cast specification: 30200 [IBM][System i Access ODBC Driver]Column 1: CWB0111 - A buffer passed to a system call is too small to hold return data (SQLFetchScroll[30200] at ext/pdo_odbc/odbc_stmt.c:624) ``` ### Proposed Workaround / Solution in pdo_odbc Just like pdo_odbc already has driver-specific adjustments in odbc_stmt_describe() for SQL Server lengths, pdo_odbc could ensure a minimum buffer of 6 bytes for SQL_BIT columns to safely accommodate non-compliant drivers that write "FALSE\0": ```c /* Ensure buffer can accommodate "FALSE\0" for drivers returning text booleans */ if (S->cols[colno].coltype == SQL_BIT && colsize < 6) { colsize = 5; // colsize + 1 will allocate 6 bytes S->cols[colno].datalen = colsize; } ``` ### PHP Version ```plain PHP 8.5.11 (cli) (built: Sep 24 2026 19:07:29) (NTS) Copyright (c) The PHP Group Built by https://github.com/docker-library/php Zend Engine v4.5.11, Copyright (c) Zend Technologies with Xdebug v3.5.3, Copyright (c) 2002-2026, by Derick Rethans with Zend OPcache v8.5.11, Copyright (c), by Zend Technologies ``` ### Operating System Ubuntu 26.04

« previous php.bugs (#253051) next »