[Mono-bugs] [Bug 456234] New: ODBC utf8: incorrect OdbcDataReader.GetValue() result for VARCHAR if byte size >=255
bugzilla_noreply at novell.com
bugzilla_noreply at novell.com
Wed Dec 3 16:50:22 EST 2008
https://bugzilla.novell.com/show_bug.cgi?id=456234
Summary: ODBC utf8: incorrect OdbcDataReader.GetValue() result
for VARCHAR if byte size >=255
Product: Mono: Class Libraries
Version: 1.9
Platform: x86
OS/Version: Linux
Status: NEW
Severity: Normal
Priority: P5 - None
Component: Sys.Data
AssignedTo: bnc-blr-team-mono at forge.provo.novell.com
ReportedBy: amc1999 at gmail.com
QAContact: mono-bugs at lists.ximian.com
Found By: ---
Created an attachment (id=257867)
--> (https://bugzilla.novell.com/attachment.cgi?id=257867)
test
Found and fixed for 1.9 version, but 1.9, 2.0, 2.2 and SVN have same code in
that place and, i assume, same bug. Also because OdbcDataReader.GetValue used
by DataSet to get field values bug is applicable here too.
Description:
------------
OdbcDataReader.GetValue() return incorrect result if:
size of utf8 string >=255 bytes and one of:
- ODBC driver return StrLen_or_IndPtr=SQL_NO_TOTAL from SQLGetData()
- or utf8 multi-byte character falls across 255 internal byte buffer boundary
Steps to reproduce:
-------------------
1. SQL's and ODBC drivers:
IBM DB2 9.x + IBM ODBC driver
PostgreSQL >= 8.2 ODBC driver >= 8.01
MySQL 5.0.x, mysql-connector-ODBC >= 3.51.17 (not 5.xx)
SQLite3 with ODBC driver >= 0.79
2. Create table with VARCHAR >= 255 field and insert test value:
123456789...250chars...123ñç
End of string bytes are:
[250]=49 [251]=50 [252]=51 [253]=195 [254]=177 [255]=195 [256]=167
CREATE TABLE utf8_255_test(ival INT NOT NULL, sval VARCHAR(300));
INSERT INTO utf8_255_test(ival, sval) VALUES (255,
'1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123ñç');
3. Use DataSet or OdbcDataReader to get field value:
SELECT sval FROM utf8_255_test WHERE sval LIKE '%123ñç';
Current result:
---------------
For most of the drivers you'll get:
123456789...250chars...123ç
it is a bug because has no ñ symbol, which falls across the 255 buffer
boundary
Or with SQLite 0.79 ODBC result is:
ç
one single character and there is nothing else.
A variation of the test for SQLite and other drivers which returns
StrLen_or_IndPtr=SQL_NO_TOTAL from SQLGetData() is to insert any
VARCHAR(>=255). Result of SELECT returned by DataSet or OdbcDataReader will be
string tail after 255. For example, 123456789...250chars...1234567 returns 567
only.
>From attached test you'll get:
DSN=psql-tst;UID=tst;PWD=tst;
End of string bytes: [250]=49 [251]=50 [252]=51 [253]=195 [254]=177
[255]=195 [256]=167
CREATE TABLE utf8_255_test(ival INT NOT NULL, sval VARCHAR(300)) : -1
INSERT INTO utf8_255_test(ival, sval) VALUES (1, 'test') : 1
INSERT INTO utf8_255_test(ival, sval) VALUES (255,
'1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123ñç')
: 1
SELECT ival, sval FROM utf8_255_test ORDER BY 1
Rows.Count=2 Columns.Count=2
ival | sval |
[0]: 1 | test |
[1]: 255 |
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123ç
|
SELECT sval FROM utf8_255_test WHERE sval LIKE '%123ñç' :
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123ç
----Test FAILED----
DROP TABLE utf8_255_test : -1
Expected result:
----------------
DRIVER=SQLite3;Database=tst.db;
End of string bytes: [250]=49 [251]=50 [252]=51 [253]=195 [254]=177
[255]=195 [256]=167
CREATE TABLE utf8_255_test(ival INT NOT NULL, sval VARCHAR(300)) : -1
INSERT INTO utf8_255_test(ival, sval) VALUES (1, 'test') : 1
INSERT INTO utf8_255_test(ival, sval) VALUES (255,
'1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123ñç')
: 1
SELECT ival, sval FROM utf8_255_test ORDER BY 1
Rows.Count=2 Columns.Count=2
ival | sval |
[0]: 1 | test |
[1]: 255 |
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123ñç
|
SELECT sval FROM utf8_255_test WHERE sval LIKE '%123ñç' :
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123ñç
++++Test passed OK++++
DROP TABLE utf8_255_test : -1
Fixed:
------
1.Use Decoder.GetChars() instead of Encoding.GetString() to maintain bytes
across 255 buffer boundary.
2.Handle SQL_NO_TOTAL as result of SQLGetData(..., SQLLEN *StrLen_or_IndPtr);
Other Issues:
-------------
Similar logic is used for NVARCHAR in OdbcDataReader and it also may need to
use Decoder.GetChars() instead of Encoding.GetString(), but I can not test it.
--
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
More information about the mono-bugs
mailing list