[pdo_odbc] Buffer overflow / CWB0111 on SQL_BIT columns with IBM i Access ODBC Driver
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 68/100
調査の方向性
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時間
- マージ済み PR(30日)
- 151
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
php/php-src のほかの issue
-
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()オープン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
php/php-src#24552 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
master: part of the mbstring bailout fix got lost in a merge対応中かも @lazerg が 3 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
-
priority:medium type:chore
難易度 1/5 1〜3時間 初心者へのやさしさ 84/100
crazy-goat/php-fpm-ng#1041 ·
メンテナーはふだん 1 日以内に返信
-
Test failure on FreeBSD: #26 unexpected system_clock source対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープンlow priority rt_lib tests
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
メンテナーはふだん 1 日以内に返信
-
good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100