Skip to content

Commit 832d8e7

Browse files
committed
Fix heap-buffer-overflow in ConvertingString<> state buffer allocation
On Linux, sizeof(wchar_t) = 4 bytes but sizeof(SQLWCHAR) = 2 bytes (unixODBC defines SQLWCHAR as unsigned short). The ConvertingString constructor used sizeof(wchar_t) to convert a byte-count argument into the number of narrow characters needed: lengthString = length / sizeof(wchar_t); // = 12/4 = 3 on Linux For SQLGetDiagRecW the state buffer is declared as State(12, sqlState), giving lengthString=3 and Alloc() allocating 3+2=5 bytes. strcpy() then writes the 5-character SQL state plus its NUL terminator (6 bytes) into that 5-byte buffer, producing a 1-byte heap-buffer-overflow caught by AddressSanitizer. The same latent bug exists in SQLErrorW (same State(12, sqlState) pattern). Fix: divide by sizeof(SQLWCHAR) instead of sizeof(wchar_t). sizeof(SQLWCHAR) == 2 on all platforms (Windows: SQLWCHAR=wchar_t=2; Linux/unixODBC: SQLWCHAR=unsigned short=2), so the formula now yields: lengthString = 12 / sizeof(SQLWCHAR) = 6 and Alloc() allocates 6+2=8 bytes, comfortably holding the SQL state. On Windows sizeof(wchar_t)==sizeof(SQLWCHAR)==2, so this change is a no-op there. Found by: AddressSanitizer (introduced in CI via PR #288/#289) Test: DataTypeTest.SmallintRoundTrip -> ExecIgnoreError -> SQLExecDirect -> unixODBC dispatcher -> SQLGetDiagRecW -> sqlGetDiagRec(strcpy)
1 parent 2e5af48 commit 832d8e7

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

MainUnicode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class ConvertingString
8585
if ( length == SQL_NTS )
8686
lengthString = 0;
8787
else if ( retCountOfBytes )
88-
lengthString = length / sizeof(wchar_t);
88+
lengthString = length / sizeof(SQLWCHAR);
8989
else
9090
lengthString = length;
9191
}

0 commit comments

Comments
 (0)