Skip to content

Buggy drivers that keep returning empty strings in SQLGetData can get PDO_ODBC stuck in a loop #21534

@NattyNarwhal

Description

@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, 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.)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions