Skip to content

Commit 4781096

Browse files
lanfeust69mgravell
andauthored
Fix a couple of semi-edge-cases (#199)
* Avoid throwing on IDisposable * Avoid throwing in ProtoBufMarshallerFactory.CanSerialize There is at least one situation where the underlying protobuf TypeModel throws a NotSupportedException : when asking about an array of arrays. While this seems doubtful (it should simply return false), it is easy enough to prevent this from trashing the whole service. * Remove remnant of old code No longer any reason to handle delegates specifically : it will be done naturally by the marshallerCache (and who knows, maybe it *can* serialize some delegates !). Moreover, this could misinterpret a signature as valid without parameter, with somewhat weird consequences. --------- Co-authored-by: Marc Gravell <[email protected]>
1 parent fc2761c commit 4781096

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

src/protobuf-net.Grpc/Configuration/ProtoBufMarshallerFactory.cs

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using ProtoBuf.Meta;
1+
using ProtoBuf.Meta;
22
using System;
33
using System.Buffers;
44
using System.IO;
@@ -187,9 +187,19 @@ private T ContextualDeserialize<T>(global::Grpc.Core.DeserializationContext cont
187187
/// Indicates whether a type should be considered as a serializable data type
188188
/// </summary>
189189
protected internal override bool CanSerialize(Type type)
190-
=> HasSingle(Options.ContractTypesOnly)
191-
? _model.CanSerializeContractType(type)
192-
: _model.CanSerialize(type);
190+
{
191+
try
192+
{
193+
return HasSingle(Options.ContractTypesOnly)
194+
? _model.CanSerializeContractType(type)
195+
: _model.CanSerialize(type);
196+
}
197+
catch (NotSupportedException)
198+
{
199+
// a typical case is the use of jagged arrays
200+
return false;
201+
}
202+
}
193203

194204
/// <summary>
195205
/// Deserializes an object from a payload

src/protobuf-net.Grpc/Internal/ContractOperation.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Reflection;
44
using Grpc.Core;
@@ -212,8 +212,6 @@ static TypeCategory GetCategory(MarshallerCache marshallerCache, Type type, IBin
212212
if (genType == typeof(AsyncServerStreamingCall<>)) return TypeCategory.AsyncServerStreamingCall;
213213
}
214214

215-
if (typeof(Delegate).IsAssignableFrom(type)) return TypeCategory.None; // yeah, that's not going to happen
216-
217215
if (marshallerCache.CanSerializeType(type)) return TypeCategory.Data;
218216
bindContext?.LogWarning("Type cannot be serialized; ignoring: {0}", type.FullName);
219217
return TypeCategory.Invalid;

src/protobuf-net.Grpc/Internal/ProxyEmitter.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Grpc.Core;
1+
using Grpc.Core;
22
using ProtoBuf.Grpc.Client;
33
using ProtoBuf.Grpc.Configuration;
44
using System;
@@ -212,7 +212,12 @@ FieldBuilder Marshaller(Type forType)
212212
var shallMethodBeImplemented = isService || isMethodInherited;
213213
if (!(shallMethodBeImplemented && ContractOperation.TryIdentifySignature(iMethod, binderConfig, out var op, null)))
214214
{
215-
il.ThrowException(typeof(NotSupportedException));
215+
// it is frequent for some infrastructure code to always call Dispose() on IDisposable,
216+
// for instance Asp.Net Core dependency injection, so we don't want to throw in this case
217+
if (iType == typeof(IDisposable) && iMethod.Name == nameof(IDisposable.Dispose))
218+
il.Emit(OpCodes.Ret);
219+
else
220+
il.ThrowException(typeof(NotSupportedException));
216221
continue;
217222
}
218223

0 commit comments

Comments
 (0)