[pdo_odbc] Buffer overflow / CWB0111 on SQL_BIT columns with IBM i Access ODBC Driver
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
研究方向
Start in ext/pdo_odbc/odbc_stmt.c at odbc_stmt_describe(), where SQL_DESC_DISPLAY_SIZE determines the SQL_BIT column buffer size; review the existing driver-specific length adjustments and the SQLBindCol call. Check whether the proposed minimum buffer handles the reported IBM i Access ODBC Driver behavior, then add or locate coverage for SQL_BIT fetching. Done means the reported BOOLEAN query fetches without CWB0111 while existing PDO ODBC behavior remains covered.
由索引模型根據 Issue 內容生成。
描述
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:
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():
pdo_odbcqueriesSQL_DESC_DISPLAY_SIZEviaSQLColAttribute:rc = SQLColAttribute(S->stmt, colno+1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &displaysize); colsize = displaysize;- For an IBM i
BOOLEANcolumn (ODBC typeSQL_BIT/-7), the IBM driver reports a display size of1. - Because
colsize < LONG_COLUMN_BUFFER_SIZE(1 < 256),pdo_odbcallocates a 2-byte fixed buffer (emalloc(colsize + 1)):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); - While the ODBC specification states that
SQL_BITconverted toSQL_C_CHARshould 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). - During
SQLFetchScroll, writing"FALSE\0"(6 bytes) into the 2-byte buffer triggers the driver'sCWB0111buffer 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-iaccess1.1.0.29-1.0 /libcwbodbc.so) - Database: IBM Db2 for i (IBM i 7.5+)
Steps to Reproduce
- Connect to an IBM i 7.5+ system with
pdo_odbc. - Create a table with a native
BOOLEANcolumn:CREATE TABLE test_bool (id INT, is_active BOOLEAN); INSERT INTO test_bool VALUES (1, FALSE); - Run a query through PDO:
$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
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":
/* 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
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
- 主要語言
- C
- 星號
- 40.7k
- 分支
- 8.3k
- 平均合併
- 2 天 16 小時
- 30 天內合併 PR
- 151
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 沒有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
php/php-src 的其他 Issue
-
sapi/fpm/tests/tester.inc can send SIGUSR2 to pid 0, killing run-tests.php可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉Bug Status: Needs Triage
難度 2/5 1-3 小時 新手友好度 78/100
維護者通常 1 天內回覆
-
zend_set_local_var() overwrites existing compiled variable (CV) zval without calling zval_ptr_dtor()可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉Bug Status: Needs Triage
難度 2/5 1-3 小時 新手友好度 82/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 72/100
維護者通常 1 天內回覆
-
Case-insensitive substr_compare, ksort, krsort are still locale-dependent可能已有人在做 @lazerg 於 3 天前認領。 未關閉Bug Extension: standard Status: Verified
難度 2/5 1-3 小時 新手友好度 73/100
維護者通常 1 天內回覆
-
master: part of the mbstring bailout fix got lost in a merge可能已有人在做 @lazerg 於 4 天前認領。 未關閉
難度 2/5 1-3 小時 新手友好度 78/100
維護者通常 1 天內回覆
相似的 Issue
-
難度 2/5 1-3 小時 新手友好度 65/100
-
難度 2/5 1-3 小時 新手友好度 78/100
HexaCluster/credcheck#86 ·
-
難度 2/5 1-3 小時 新手友好度 66/100
mongodb/winkerberos#175 ·
-
bug
難度 2/5 1-3 小時 新手友好度 74/100
AOMediaCodec/SVT-AV1#3320 ·
-
difficulty: easy
難度 2/5 1-3 小時 新手友好度 64/100