System.Data.SQLite
View Ticket
Not logged in
Ticket UUID: 5535448538b1e99fe2ffcf1ea9ecfff2368355a4
Title: SQLiteDataReader.GetInt*() functions return incorrect values
Status: Closed Type: Code_Defect
Severity: Important Priority: Blocker
Subsystem: Data_Reader Resolution: Fixed
Last Modified: 2016-12-14 19:38:13
Version Found In: 1.0.102.0
User Comments:
anonymous added on 2016-10-27 07:04:07:
The SQLiteDataReader functions GetByte(), GetInt16(), GetInt32() and GetInt64() return incorrect values in some situations. See the provided test code below or at Pastebin: [http://pastebin.com/GAsz0ekk]



SQLiteConnection connection = ...;

using (SQLiteCommand command = new SQLiteCommand("SELECT ?, 0x10FFFFFFF, 0x1FFFFFFFF;", connection)) {

	// Add a command parameter with the value 0xFFFFFFFF
	SQLiteParameter parameter = new SQLiteParameter();
	parameter.Value = 0xFFFFFFFF;
	command.Parameters.Add(parameter);

	SQLiteDataReader reader = command.ExecuteReader();
	reader.Read();

	// Test getting 0xFFFFFFFF as Int64
	// EXPECTED: 0xFFFFFFFF
	// ACTUAL: -1
	// Test FAILS
	Assert.AreEqual(0xFFFFFFFF, reader.GetInt64(0));

	// Test getting 0x10FFFFFFF as Int16
	// EXPECTED: OverflowException
	// ACTUAL: OverflowException
	// Test PASSES
	try {
		short value = reader.GetInt16(1);
		Assert.Fail();
	} catch (OverflowException) { }

	// Test getting 0x1FFFFFFFF as Int16
	// EXPECTED: OverflowException
	// ACTUAL: -1
	// Test FAILS
	try {
		short value = reader.GetInt16(2);
		Assert.Fail();
	} catch (OverflowException) { }

	// Test getting 0x10FFFFFFF as Int32
	// EXPECTED: OverflowException
	// ACTUAL: 0xFFFFFFF
	// Test FAILS
	try {
		int value = reader.GetInt32(1);
		Assert.Fail();
	} catch (OverflowException) { }

	// Test getting 0x1FFFFFFFF as Int32
	// EXPECTED: OverflowException
	// ACTUAL: -1
	// Test FAILS
	try {
		int value = reader.GetInt32(2);
		Assert.Fail();
	} catch (OverflowException) { }
}

mistachkin added on 2016-10-27 19:27:31:
Part of the problem here is the lack of any column type information for the
values being used in the SELECT.

This makes the affinity undefined for these values, which prevents things from
working as normal.

mistachkin added on 2016-10-27 19:53:49:
Using the NoVerifyTypeAffinity connection flag helps with this situation.

While investigating this issue, I noticed several of the SQLiteDataReader
method overloads (e.g. GetByte, GetInt16, and GetChar) were calling into
the Convert class when they should not be.  With this fixed (and by using
the NoVerifyTypeAffinity connection flag), there should be no exceptions
raised when reading the values.

mistachkin added on 2016-10-27 20:21:11:
I've now fixed the issues that I found related to this ticket.  The behavior is
now consistent; however, it may not be exactly what you would expect.  Generally,
reading integer values from the data reader will NOT throw exceptions, even if
the underlying value does not actually fit into the requested type.

See check-in [2b70123e05] on trunk.