[php-src] Issue #21534: Buggy drivers that keep returning empty strings in SQLGetData can get PDO_ODBC stuck in a loop
[email protected] (NattyNarwhal)
| Newsgroups | php.bugs |
|---|---|
| Message-ID | <[email protected]> |
Issue: https://github.com/php/php-src/issues/21534 Author: NattyNarwhal Happened in PHP 8.4.15. The driver here is being quite silly. Not sure why it decided to do it for this data (and did so in a reproducible manner, without a workaround). unixODBC trace when it happens: ``` [...getting the column in chunks] [ODBC][286773][1774288047.961549][SQLGetData.c][237] Entry: Statement = 180ad0570 Column Number = 1 Target Type = 1 SQL_CHAR Buffer Length = 256 Target Value = 70000000007c600 StrLen Or Ind = 70000000008b190 [ODBC][286773][1774288047.961640][SQLGetData.c][545] Exit:[SQL_SUCCESS_WITH_INFO] Buffer = Indicator = -4 Strlen Or Ind = 70000000008b190 -> -4 (64 bits) [ODBC][286773][1774288047.961671][SQLGetData.c][237] Entry: Statement = 180ad0570 Column Number = 1 Target Type = 1 SQL_CHAR Buffer Length = 256 Target Value = 70000000007c600 StrLen Or Ind = 70000000008b190 [ODBC][286773][1774288047.961761][SQLGetData.c][545] Exit:[SQL_SUCCESS_WITH_INFO] Buffer = Indicator = -4 Strlen Or Ind = 70000000008b190 -> -4 (64 bits) [ODBC][286773][1774288047.961792][SQLGetData.c][237] Entry: Statement = 180ad0570 Column Number = 1 Target Type = 1 SQL_CHAR Buffer Length = 256 Target Value = 70000000007c600 StrLen Or Ind = 70000000008b190 [ODBC][286773][1774288047.961828][SQLGetData.c][545] Exit:[SQL_SUCCESS] Buffer = [<redacted...>] Strlen Or Ind = 70000000008b190 -> 193 (64 bits) [ODBC][286773][1774288047.961859][SQLGetData.c][237] Entry: Statement = 180ad0570 Column Number = 1 Target Type = 1 SQL_CHAR Buffer Length = 256 Target Value = 70000000007c600 StrLen Or Ind = 70000000008b190 [ODBC][286773][1774288047.961891][SQLGetData.c][545] Exit:[SQL_SUCCESS] Buffer = [] Strlen Or Ind = 70000000008b190 -> 0 (64 bits) [ODBC][286773][1774288047.961921][SQLGetData.c][237] Entry: Statement = 180ad0570 Column Number = 1 Target Type = 1 SQL_CHAR Buffer Length = 256 Target Value = 70000000007c600 StrLen Or Ind = 70000000008b190 [ODBC][286773][1774288047.961953][SQLGetData.c][545] Exit:[SQL_SUCCESS] Buffer = [] Strlen Or Ind = 70000000008b190 -> 0 (64 bits) [ODBC][286773][1774288047.961984][SQLGetData.c][237] Entry: Statement = 180ad0570 Column Number = 1 Target Type = 1 SQL_CHAR Buffer Length = 256 Target Value = 70000000007c600 StrLen Or Ind = 70000000008b190 [ODBC][286773][1774288047.962016][SQLGetData.c][545] Exit:[SQL_SUCCESS] Buffer = [] Strlen Or Ind = 70000000008b190 -> 0 (64 bits) [empty strings forever...] ``` In [this loop](https://github.com/php/php-src/blob/1655d57751a9461d2d5095e950896389a7aba290/ext/pdo_odbc/odbc_stmt.c#L731), it'll continue to just realloc and copy nothing. (In 8.5, this changes to use a dynamic buffer size, but the logic there is the same.)