Skip to content

Commit

Permalink
Stop setting current index local which is nonexistent in ValueTuple d…
Browse files Browse the repository at this point in the history
…eserializer (#1280)

* String and byte[] tuple elements cause InvalidProgramException

* Stop setting current index local which is nonexistent in ValueTuple deserializer
  • Loading branch information
jnm2 authored and mgravell committed Jun 13, 2019
1 parent fcd8a70 commit 8b49eb6
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
14 changes: 14 additions & 0 deletions Dapper.Tests/TupleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,19 @@ public void TupleReturnValue_Works_With15Elements()
Assert.Equal(14, val.e14);
Assert.Equal(15, val.e15);
}

[Fact]
public void TupleReturnValue_Works_WithStringField()
{
var val = connection.QuerySingle<ValueTuple<string>>("select '42'");
Assert.Equal("42", val.Item1);
}

[Fact]
public void TupleReturnValue_Works_WithByteField()
{
var val = connection.QuerySingle<ValueTuple<byte[]>>("select 0xDEADBEEF");
Assert.Equal(new byte[] { 0xDE, 0xAD, 0xBE, 0xEF }, val.Item1);
}
}
}
10 changes: 6 additions & 4 deletions Dapper/SqlMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3178,7 +3178,7 @@ private static void GenerateValueTupleDeserializer(Type valueTupleType, IDataRea

private static void GenerateDeserializerFromMap(Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing, ILGenerator il)
{
il.DeclareLocal(typeof(int));
var currentIndexDiagnosticLocal = il.DeclareLocal(typeof(int));
il.DeclareLocal(type);
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Stloc_0);
Expand Down Expand Up @@ -3292,6 +3292,10 @@ private static void GenerateDeserializerFromMap(Type type, IDataReader reader, i
Label finishLabel = il.DefineLabel();
Type memberType = item.MemberType;

// Save off the current index for access if an exception is thrown
EmitInt32(il, index);
il.Emit(OpCodes.Stloc, currentIndexDiagnosticLocal);

LoadReaderValueOrBranchToDBNullLabel(il, index, ref enumDeclareLocal, valueCopyLocal, reader.GetFieldType(index), memberType, out var isDbNullLabel);

if (specializedConstructor == null)
Expand Down Expand Up @@ -3379,7 +3383,7 @@ private static void GenerateDeserializerFromMap(Type type, IDataReader reader, i
}
il.MarkLabel(allDone);
il.BeginCatchBlock(typeof(Exception)); // stack is Exception
il.Emit(OpCodes.Ldloc_0); // stack is Exception, index
il.Emit(OpCodes.Ldloc, currentIndexDiagnosticLocal); // stack is Exception, index
il.Emit(OpCodes.Ldarg_0); // stack is Exception, index, reader
LoadLocal(il, valueCopyLocal); // stack is Exception, index, reader, value
il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod(nameof(SqlMapper.ThrowDataException)), null);
Expand Down Expand Up @@ -3413,8 +3417,6 @@ private static void LoadReaderValueOrBranchToDBNullLabel(ILGenerator il, int ind
isDbNullLabel = il.DefineLabel();
il.Emit(OpCodes.Ldarg_0); // stack is now [...][reader]
EmitInt32(il, index); // stack is now [...][reader][index]
il.Emit(OpCodes.Dup);// stack is now [...][reader][index][index]
il.Emit(OpCodes.Stloc_0);// stack is now [...][reader][index]
il.Emit(OpCodes.Callvirt, getItem); // stack is now [...][value-as-object]

if (valueCopyLocal != null)
Expand Down

0 comments on commit 8b49eb6

Please sign in to comment.