From 3570935f568b9101321f30d5fe88983cff6784cd Mon Sep 17 00:00:00 2001 From: Julia Seward Date: Wed, 4 Oct 2023 18:42:34 -0400 Subject: [PATCH 1/2] feat: add type safe check when sending custom request / response types --- .../Utils/TypeSafety.cs | 24 +++++++++++++++++++ .../Controllers/TypedMessageHandler.cs | 22 +++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 Core Modules/WalletConnectSharp.Common/Utils/TypeSafety.cs diff --git a/Core Modules/WalletConnectSharp.Common/Utils/TypeSafety.cs b/Core Modules/WalletConnectSharp.Common/Utils/TypeSafety.cs new file mode 100644 index 0000000..1903927 --- /dev/null +++ b/Core Modules/WalletConnectSharp.Common/Utils/TypeSafety.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json; + +namespace WalletConnectSharp.Common.Utils; + +public static class TypeSafety +{ + private static JsonSerializerSettings Settings = + new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto }; + + public static void EnsureTypeSerializerSafe(T testObject) + { + // unwrapping and rewrapping the object + // to / from JSON should tell us + // if it's serializer safe, since + // we are using the serializer to test + UnsafeJsonRewrap(testObject); + } + + public static TR UnsafeJsonRewrap(this T source) + { + var json = JsonConvert.SerializeObject(source); + return JsonConvert.DeserializeObject(json); + } +} diff --git a/WalletConnectSharp.Core/Controllers/TypedMessageHandler.cs b/WalletConnectSharp.Core/Controllers/TypedMessageHandler.cs index a29a37c..c542234 100644 --- a/WalletConnectSharp.Core/Controllers/TypedMessageHandler.cs +++ b/WalletConnectSharp.Core/Controllers/TypedMessageHandler.cs @@ -1,6 +1,7 @@ using Newtonsoft.Json; using WalletConnectSharp.Common.Logging; using WalletConnectSharp.Common.Model.Errors; +using WalletConnectSharp.Common.Utils; using WalletConnectSharp.Core.Interfaces; using WalletConnectSharp.Core.Models.Relay; using WalletConnectSharp.Crypto.Models; @@ -14,6 +15,7 @@ public class TypedMessageHandler : ITypedMessageHandler { private bool _initialized = false; private Dictionary _decodeOptionsMap = new Dictionary(); + private HashSet _typeSafeCache = new HashSet(); public EventDelegator Events { get; } @@ -303,6 +305,8 @@ public DecodeOptions DecodeOptionForTopic(string topic) /// The id of the request sent public async Task SendRequest(string topic, T parameters, long? expiry = null, EncodeOptions options = null) { + EnsureTypeIsSerializerSafe(parameters); + var method = RpcMethodAttribute.MethodForType(); var payload = new JsonRpcRequest(method, parameters); @@ -339,6 +343,8 @@ public async Task SendRequest(string topic, T parameters, long? exp /// The response type public async Task SendResult(long id, string topic, TR result, EncodeOptions options = null) { + EnsureTypeIsSerializerSafe(result); + var payload = new JsonRpcResponse(id, null, result); var message = await this.Core.Crypto.Encode(topic, payload, options); var opts = RpcResponseOptionsFromTypes(); @@ -356,6 +362,9 @@ public async Task SendResult(long id, string topic, TR result, EncodeOpti /// The response type public async Task SendError(long id, string topic, Error error, EncodeOptions options = null) { + // Type Error is always serializer safe + // EnsureTypeIsSerializerSafe(error); + var payload = new JsonRpcResponse(id, error, default); var message = await this.Core.Crypto.Encode(topic, payload, options); var opts = RpcResponseOptionsFromTypes(); @@ -367,5 +376,18 @@ public void Dispose() { Events?.Dispose(); } + + private void EnsureTypeIsSerializerSafe(T testObject) + { + var typeString = typeof(T).FullName; + if (_typeSafeCache.Contains(typeString)) + return; + + // Throw any serialization exceptions now + // before it's too late + TypeSafety.EnsureTypeSerializerSafe(testObject); + + _typeSafeCache.Add(typeString); + } } } From 571923636407feda941c5d295e7cadb6b4656112 Mon Sep 17 00:00:00 2001 From: Julia Seward Date: Wed, 4 Oct 2023 18:46:36 -0400 Subject: [PATCH 2/2] chore: use same settings as storage serializer --- .../WalletConnectSharp.Common/Utils/TypeSafety.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Core Modules/WalletConnectSharp.Common/Utils/TypeSafety.cs b/Core Modules/WalletConnectSharp.Common/Utils/TypeSafety.cs index 1903927..d74387d 100644 --- a/Core Modules/WalletConnectSharp.Common/Utils/TypeSafety.cs +++ b/Core Modules/WalletConnectSharp.Common/Utils/TypeSafety.cs @@ -13,12 +13,15 @@ public static void EnsureTypeSerializerSafe(T testObject) // to / from JSON should tell us // if it's serializer safe, since // we are using the serializer to test - UnsafeJsonRewrap(testObject); + UnsafeJsonRewrap(testObject, Settings); } - public static TR UnsafeJsonRewrap(this T source) + public static TR UnsafeJsonRewrap(this T source, JsonSerializerSettings settings = null) { - var json = JsonConvert.SerializeObject(source); + var json = settings == null ? + JsonConvert.SerializeObject(source) : + JsonConvert.SerializeObject(source, settings); + return JsonConvert.DeserializeObject(json); } }