Skip to content

[C++][FlightRPC][ODBC] SQL_ATTR_CURRENT_CATALOG (and SQL_DESC_NAME) decode a wide string with the byte-wise decoder #50852

Description

@vikrantpuppala

Describe the bug, including details regarding any error messages, version, and platform.

In the Arrow Flight SQL ODBC driver, ODBCConnection::SetConnectAttr decodes
the SQL_ATTR_CURRENT_CATALOG value with the wrong string decoder when the
call arrives through a wide (Unicode / *W) entry point.

// odbc_impl/odbc_connection.cc
case SQL_ATTR_CURRENT_CATALOG: {
  std::string catalog;
  if (is_unicode) {
    SetAttributeUTF8(value, string_length, catalog);      // <-- wrong
  } else {
    SetAttributeSQLWCHAR(value, string_length, catalog);  // <-- wrong
  }
  ...

is_unicode selects the buffer width, not "needs conversion":

  • A unicode (SQLSetConnectAttrW) call hands over a wide SQLWCHAR buffer
    and must be decoded with SetAttributeSQLWCHAR.
  • A non-unicode (SQLSetConnectAttrA) call hands over a byte string and is
    decoded with SetAttributeUTF8.

The two branches are swapped. When a wide catalog name is decoded with the
byte-wise SetAttributeUTF8, the wide buffer is misread: with a null-terminated
(SQL_NTS) length it is truncated at the first embedded NUL of the wide
encoding (e.g. UTF-16 "odbc""o"); with an explicit length it is stored
raw, embedded NULs and all (UTF-16 "my_catalog"
"m\0y\0_\0c\0a\0t\0a\0l\0o\0g\0"). Either way the stored catalog is wrong.

The correct mapping is already established by the getter side: GetStringAttribute
(in attribute_utils.h) maps is_unicode == true to GetAttributeSQLWCHAR.
The setter for SQL_ATTR_CURRENT_CATALOG inverts it.

The same class of bug exists in ODBCDescriptor::SetField for SQL_DESC_NAME,
which unconditionally uses the byte-wise SetAttributeUTF8 even though the
matching getter (GetField / SQL_DESC_NAME) reads the field back with
GetAttributeSQLWCHAR — so the field is stored wide-origin but decoded
byte-wise on the way in.

Impact: an application that sets a multi-character catalog through the
wide entry point gets a corrupted catalog name back, so subsequent catalog
scoping operates on the wrong (or a non-existent) catalog.

Introduced by:

Component(s)

C++, FlightRPC

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions