Bug #48699 | c/ODBC cuts BINARY parameter after encountering first 00 | ||
---|---|---|---|
Submitted: | 11 Nov 2009 20:10 | Modified: | 19 Nov 2009 15:15 |
Reporter: | Tonci Grgin | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | Connector / ODBC | Severity: | S2 (Serious) |
Version: | all | OS: | Any |
Assigned to: | Lawrenty Novitsky | CPU Architecture: | Any |
[11 Nov 2009 20:10]
Tonci Grgin
[13 Nov 2009 8:32]
Tonci Grgin
Bug#48752 was marked as duplicate of this report.
[13 Nov 2009 9:54]
Bogdan Degtyariov
patch and test case
Attachment: patch48699.diff (text/x-diff), 2.96 KiB.
[13 Nov 2009 9:56]
Bogdan Degtyariov
The initial test case does not reproduce the problem because it does not use row-wise parameter binding. Please see the test case in the attached file.
[13 Nov 2009 16:20]
Lawrenty Novitsky
If we agree this is not a bug, and i tend to think so, the outcome of this bug should be following patch: === modified file 'driver/execute.c' --- driver/execute.c 2009-10-07 20:43:23 +0000 +++ driver/execute.c 2009-11-13 16:15:14 +0000 @@ -276,13 +276,20 @@ *toptr= add_to_buffer(net,*toptr,"NULL",4); return SQL_SUCCESS; } + /* + According to http://msdn.microsoft.com/en-us/library/ms710963%28VS.85%29.aspx + + "... If StrLen_or_IndPtr is a null pointer, the driver assumes that all^M + input parameter values are non-NULL and that character and *binary* data + is null-terminated." + */ else if (!octet_length_ptr || *octet_length_ptr == SQL_NTS) { if (data) { if (aprec->concise_type == SQL_C_WCHAR) length= sqlwcharlen((SQLWCHAR *)data) * sizeof(SQLWCHAR); - else /* TODO this is stupid, check condition above, shouldn't we be checking only octet_length, not ptr? */ + else length= strlen(data); if (!octet_length_ptr && aprec->octet_length > 0 && Because seems like quote from msdn answers the question in the comment this patch removes.
[16 Nov 2009 4:08]
Bogdan Degtyariov
Lawrin, thank you. Confirmed as not a bug.
[19 Nov 2009 7:57]
Tonci Grgin
Lawrin, Bogdan: We should check on this again... The above msdn link quote is only applied to null pointer value for StrLen_or_IndPtr parameter for SQLBindParameter. But not for when one calls SQLBinParameter for SQL_C_BINARY type, passing the number of bytes in C binary structure and not a null pointer for StrLen_or_IndPtr. As you see in my example, the value for input parameter StrLen_or_IndPtr for SQLBindParameter is len= strlen(buf); Following quote from MSDN should apply: http://msdn.microsoft.com/en-us/library/ms710963%28VS.85%29.aspx: StrLen_or_IndPtr Argument The StrLen_or_IndPtr argument points to a buffer that, when SQLExecute or SQLExecDirect is called, contains one of the following. (This argument sets the SQL_DESC_OCTET_LENGTH_PTR and SQL_DESC_INDICATOR_PTR record fields of the application parameter pointers.) * The length of the parameter value stored in *ParameterValuePtr. This is ignored except for character or binary C data. * SQL_NTS. The parameter value is a null-terminated string. Lawrentiy, please recheck your ruling.
[19 Nov 2009 15:15]
Lawrenty Novitsky
If to change in Tonci's example len= strlen() to len= 5, everything is gonna work just fine. strlen won't work here, because it stops counting bytes on first 0 byte. You can test the value - it will be 1. Value pointed by StrLen_Or_IndicatorPtr is used as number of bytes to copy from binary parameter. I believe that is in full accordance with the given quote from MSDN.