Skip to content

Commit 8f36991

Browse files
rukpetDmytro Ohorodniichuk
andauthored
Issue #1164 (#1795)
Fix unsigned types mapping arithmetic overflow Add tests to reproduce issue #1164 Co-authored-by: Dmytro Ohorodniichuk <[email protected]>
1 parent d7c1603 commit 8f36991

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

Dapper/SqlMapper.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3801,20 +3801,20 @@ private static void FlexibleConvertBoxedFromHeadOfStack(ILGenerator il, Type fro
38013801
switch (Type.GetTypeCode(via ?? to))
38023802
{
38033803
case TypeCode.Byte:
3804-
opCode = OpCodes.Conv_Ovf_I1_Un; break;
3804+
opCode = OpCodes.Conv_Ovf_U1_Un; break;
38053805
case TypeCode.SByte:
38063806
opCode = OpCodes.Conv_Ovf_I1; break;
38073807
case TypeCode.UInt16:
3808-
opCode = OpCodes.Conv_Ovf_I2_Un; break;
3808+
opCode = OpCodes.Conv_Ovf_U2_Un; break;
38093809
case TypeCode.Int16:
38103810
opCode = OpCodes.Conv_Ovf_I2; break;
38113811
case TypeCode.UInt32:
3812-
opCode = OpCodes.Conv_Ovf_I4_Un; break;
3812+
opCode = OpCodes.Conv_Ovf_U4_Un; break;
38133813
case TypeCode.Boolean: // boolean is basically an int, at least at this level
38143814
case TypeCode.Int32:
38153815
opCode = OpCodes.Conv_Ovf_I4; break;
38163816
case TypeCode.UInt64:
3817-
opCode = OpCodes.Conv_Ovf_I8_Un; break;
3817+
opCode = OpCodes.Conv_Ovf_U8_Un; break;
38183818
case TypeCode.Int64:
38193819
opCode = OpCodes.Conv_Ovf_I8; break;
38203820
case TypeCode.Single:

tests/Dapper.Tests/MiscTests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,43 @@ public HazGetOnlyAndCtor(int idProperty, string nameProperty)
13091309
IdProperty = idProperty;
13101310
NameProperty = nameProperty;
13111311
}
1312+
}
1313+
1314+
[Fact]
1315+
public void Issue1164_OverflowExceptionForByte()
1316+
{
1317+
const string sql = "select cast(200 as smallint) as [value]"; // 200 more than sbyte.MaxValue but less than byte.MaxValue
1318+
Issue1164Object<byte> obj = connection.QuerySingle<Issue1164Object<byte>>(sql);
1319+
Assert.StrictEqual(200, obj.Value);
1320+
}
1321+
1322+
[Fact]
1323+
public void Issue1164_OverflowExceptionForUInt16()
1324+
{
1325+
const string sql = "select cast(40000 as bigint) as [value]"; // 40000 more than short.MaxValue but less than ushort.MaxValue
1326+
Issue1164Object<ushort> obj = connection.QuerySingle<Issue1164Object<ushort>>(sql);
1327+
Assert.StrictEqual(40000, obj.Value);
1328+
}
1329+
1330+
[Fact]
1331+
public void Issue1164_OverflowExceptionForUInt32()
1332+
{
1333+
const string sql = "select cast(4000000000 as bigint) as [value]"; // 4000000000 more than int.MaxValue but less than uint.MaxValue
1334+
Issue1164Object<uint> obj = connection.QuerySingle<Issue1164Object<uint>>(sql);
1335+
Assert.StrictEqual(4000000000, obj.Value);
1336+
}
1337+
1338+
[Fact]
1339+
public void Issue1164_OverflowExceptionForUInt64()
1340+
{
1341+
const string sql = "select cast(10000000000000000000.0 as float) as [value]"; // 10000000000000000000 more than long.MaxValue but less than ulong.MaxValue
1342+
Issue1164Object<ulong> obj = connection.QuerySingle<Issue1164Object<ulong>>(sql);
1343+
Assert.StrictEqual(10000000000000000000, obj.Value);
1344+
}
1345+
1346+
private class Issue1164Object<T>
1347+
{
1348+
public T Value;
13121349
}
13131350

13141351
internal record struct One(int OID);

0 commit comments

Comments
 (0)