[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
-
difficulty: easy
难度 2/5 1-3 小时 新手友好度 64/100
-
难度 2/5 1-3 小时 新手友好度 65/100
-
难度 2/5 1-3 小时 新手友好度 76/100
ChefKissInc/Inferno#319 ·
-
llvm-tools
难度 1/5 1 小时以内 新手友好度 72/100
llvm/llvm-project#235522 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100