Skip to content

static cbNull in set_param() is unsafe — shared state may be mutated by ODBC driver #205

Description

@suyashkumar102

In set_param() in ls_odbc.c, the NULL indicator is declared static:

static SQLLEN cbNull = SQL_NULL_DATA;

The ODBC spec documents StrLen_or_IndPtr as both input and output — some drivers write back to it after execution. Because cbNull is static (shared across all calls in the process), a driver write-back corrupts the value for all subsequent NULL bindings.

The same static cbNull appears as dead code in raw_readparams_table() and raw_readparams_args() — declared but never used, likely a leftover from an earlier version.

Reproduction

demo_cbnull.c simulates set_param() with the static declaration and a conforming driver write-back:

static long cbNull = SQL_NULL_DATA;   /* mirrors ls_odbc.c line 751 */

static long bind_null(void) {
    long indicator = cbNull;
    cbNull = SQL_NTS;   /* driver write-back — ODBC spec permits this */
    return indicator;
}

The second call to bind_null() should return SQL_NULL_DATA (-1) but gets SQL_NTS (-3) because the shared static was mutated by the first call.

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions