From 170fbbaf8255452795f0ef36fe9fc7aa9bbf9ba0 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 7 Jul 2026 09:16:26 +1000 Subject: [PATCH] Throw for greedy RegisterFileConverter RegisterFileConverter matches every verified value via the default `target is T` canConvert, silently hijacking all serialization. Guard the generic overloads and point users to a concrete type or the non-generic overload that requires an explicit canConvert. Fixes #1656 --- .../RegisterFileConverterTests.cs | 21 +++++++++++++++++++ src/Verify/Splitters/Settings_Typed.cs | 10 +++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/StaticSettingsTests/RegisterFileConverterTests.cs diff --git a/src/StaticSettingsTests/RegisterFileConverterTests.cs b/src/StaticSettingsTests/RegisterFileConverterTests.cs new file mode 100644 index 0000000000..b5a784bdad --- /dev/null +++ b/src/StaticSettingsTests/RegisterFileConverterTests.cs @@ -0,0 +1,21 @@ +public class RegisterFileConverterTests : + BaseTest +{ + [Fact] + public void ObjectThrows() + { + var exception = Assert.Throws( + () => VerifierSettings.RegisterFileConverter( + (_, _) => new(null, "txt", "value"))); + Assert.Contains("too greedy", exception.Message); + } + + [Fact] + public void ObjectAsyncThrows() + { + var exception = Assert.Throws( + () => VerifierSettings.RegisterFileConverter( + (_, _) => Task.FromResult(new(null, "txt", "value")))); + Assert.Contains("too greedy", exception.Message); + } +} diff --git a/src/Verify/Splitters/Settings_Typed.cs b/src/Verify/Splitters/Settings_Typed.cs index 4891b4b9c3..848e5d49da 100644 --- a/src/Verify/Splitters/Settings_Typed.cs +++ b/src/Verify/Splitters/Settings_Typed.cs @@ -26,6 +26,7 @@ public static void RegisterFileConverter( CanConvert? canConvert = null) { InnerVerifier.ThrowIfVerifyHasBeenRun(); + ThrowIfObjectConverter(); RegisterFileConverter( (target, context) => Task.FromResult(conversion(target, context)), canConvert); @@ -36,10 +37,19 @@ public static void RegisterFileConverter( CanConvert? canConvert = null) { InnerVerifier.ThrowIfVerifyHasBeenRun(); + ThrowIfObjectConverter(); var converter = new TypeConverter((target, context) => conversion((T) target, context), DefaultCanConvert(canConvert)); typedConverters.Add(converter); } + static void ThrowIfObjectConverter() + { + if (typeof(T) == typeof(object)) + { + throw new("RegisterFileConverter is too greedy since object matches all verified values. Instead use a more specific type, or use the non-generic RegisterFileConverter overload that takes an explicit `canConvert`."); + } + } + public static void RegisterFileConverter( Conversion conversion, CanConvert canConvert)