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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions