[unixODBC-dev] Re: 2nd bug ? SQLGetDiagFieldW() assume buffer lengths in SQLWCHAR instead of bytes

Marc Herbert Marc.Herbert at continuent.com
Mon Jan 16 18:10:55 GMT 2006


Marc Herbert <Marc.Herbert at continuent.com> writes:

> According to article ID 294169 from Microsoft
>  <http://support.microsoft.com/default.aspx?scid=kb;EN-US;q294169>
> SQLGetDiagFieldW() should always assume sizes are in bytes. The
> rationale goes like this: "some returned values are strings, but other
> are not, so let's standardize on bytes." Check the article for more.
>
> I think I spotted a bug where unixodbc assumes some sizes are in SQLW
> characters instead of bytes, see attached patch to see where is
> located the issue.
>
> The bug is by chance not very harmful: it ends up _under_estimating
> the size of the buffer given by the user, and returning a size twice
> too big.
>
> This patch is untested, consider it as a pointer to the relevant part
> of the code and a suggestion only.
>
> This bug probably occurs at other similar places.
>

"Unfortunately", this bug seem to occur only in this one place. Let me
explain.

The ODBC function concerned here is generic: it is supposed to be able
to return both narrow char data (for instance SQL_DIAG_MESSAGE_TEXT)
or numeric data (SQL_DIAG_NATIVE) into the same (void *) pointer
provided by the user.

So I thought there were several instances of the code snippet quoted
above, to deal with this genericity, depending on the SQL_DIAG_ asked
for. But there seem to be one and only one, the same _even for numeric
data_! Debugging it demonstrates that the driver manager is indeed
performing unicode to ansi conversion of... SQL_DIAG_NATIVE for
instance (whereas this is an SQLINTEGER).

Fortunately, there is a workaround: is the user application sets the
BufferLength argument (which theoretically should be ignored) to zero,
then no conversion is performed.

By the way, both patches seen so far in this thread are quite unsafe:
they gonna write to *StringLengthPtr even when the driver does not.
The application may not expect this in the case of numeric data. So if
the application did not provide a suitable buffer -> segfault.  Again,
by setting BufferLength to zero the application avoids this issue.






More information about the unixODBC-dev mailing list