[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.)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.