From 0c6d1549602e32d05efc55cfd650589636f900d2 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 16 May 2026 13:03:07 +0000
Subject: [PATCH 1/3] Initial plan
From ca80853ab9b34659edb36086fb9cb4f1bdb73d9f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 16 May 2026 13:26:29 +0000
Subject: [PATCH 2/3] Allow empty string identifiers on non-flags enums in
JsonStringEnumConverter
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/b77c051c-b5f7-4943-9c20-6e4fe34c3b37
Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com>
---
.../src/Resources/Strings.resx | 2 +-
.../Converters/Value/EnumConverter.cs | 10 ++++----
.../Serialization/EnumConverterTests.cs | 24 +++++++++++++++++++
3 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx
index b67fc02b7a5a86..8b259b4fa14212 100644
--- a/src/libraries/System.Text.Json/src/Resources/Strings.resx
+++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx
@@ -232,7 +232,7 @@
'{0}' is invalid within a JSON string. The string should be correctly escaped.
- Enum type '{0}' uses unsupported identifier '{1}'. It must not be null, empty, or containing leading or trailing whitespace. Flags enums must additionally not contain commas.
+ Enum type '{0}' uses unsupported identifier '{1}'. It must not be null nor contain leading or trailing whitespace. Flags enums must additionally not be empty nor contain commas.
'{0}' is an invalid token type for the end of the JSON payload. Expected either 'EndArray' or 'EndObject'.
diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs
index ebc89780decd41..49b7fe4802ed51 100644
--- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs
+++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs
@@ -572,11 +572,13 @@ private static string ResolveAndValidateJsonName(string name, JsonNamingPolicy?
name = namingPolicy.ConvertName(name);
}
- if (string.IsNullOrEmpty(name) || char.IsWhiteSpace(name[0]) || char.IsWhiteSpace(name[name.Length - 1]) ||
- (s_isFlagsEnum && name.Contains(',')))
+ if (name is null ||
+ (name.Length > 0 && (char.IsWhiteSpace(name[0]) || char.IsWhiteSpace(name[name.Length - 1]))) ||
+ (s_isFlagsEnum && (name.Length == 0 || name.Contains(','))))
{
- // Reject null or empty strings or strings with leading or trailing whitespace.
- // In the case of flags additionally reject strings containing commas.
+ // Reject null strings or strings with leading or trailing whitespace.
+ // In the case of flags additionally reject empty strings or strings containing commas,
+ // both of which would introduce ambiguity in flag value parsing and formatting.
ThrowHelper.ThrowInvalidOperationException_UnsupportedEnumIdentifier(typeof(T), name);
}
diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs
index ada90fab227649..cb5c58460eb033 100644
--- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs
+++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs
@@ -1259,6 +1259,7 @@ public enum EnumWithInvalidMemberName1
Value
}
+ [Flags]
public enum EnumWithInvalidMemberName2
{
[JsonStringEnumMemberName("")]
@@ -1290,6 +1291,29 @@ public enum EnumWithInvalidMemberName6
Value
}
+ [Theory]
+ [InlineData(YesOrNoOrEmpty.Yes, "\"y\"")]
+ [InlineData(YesOrNoOrEmpty.No, "\"n\"")]
+ [InlineData(YesOrNoOrEmpty.Empty, "\"\"")]
+ public static void EnumWithEmptyStringMemberName_NonFlags_RoundtripsAsExpected(YesOrNoOrEmpty value, string expectedJson)
+ {
+ string json = JsonSerializer.Serialize(value, s_optionsWithStringEnumConverter);
+ Assert.Equal(expectedJson, json);
+ Assert.Equal(value, JsonSerializer.Deserialize(json, s_optionsWithStringEnumConverter));
+ }
+
+ public enum YesOrNoOrEmpty
+ {
+ [JsonStringEnumMemberName("y")]
+ Yes,
+
+ [JsonStringEnumMemberName("n")]
+ No,
+
+ [JsonStringEnumMemberName("")]
+ Empty,
+ }
+
[Theory]
[InlineData("\"cAmElCaSe\"", EnumWithVaryingNamingPolicies.camelCase, JsonKnownNamingPolicy.SnakeCaseUpper)]
[InlineData("\"cAmElCaSe\"", EnumWithVaryingNamingPolicies.camelCase, JsonKnownNamingPolicy.SnakeCaseLower)]
From 36a53ea737f9dc007a61a95839d6630383f5c9be Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 18 May 2026 13:35:43 +0000
Subject: [PATCH 3/3] Add flags-enum test coverage for empty-string member name
rejection
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/e6c2eed7-d610-4d2a-ba79-80c4760a113d
Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com>
---
.../Serialization/EnumConverterTests.cs | 27 +++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs
index cb5c58460eb033..663ef75ba83482 100644
--- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs
+++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs
@@ -1314,6 +1314,33 @@ public enum YesOrNoOrEmpty
Empty,
}
+ [Fact]
+ public static void EnumWithEmptyStringMemberName_Flags_Throws()
+ {
+ string expectedExceptionMessage = $"Enum type '{nameof(YesOrNoOrEmptyFlags)}' uses unsupported identifier ''.";
+
+ InvalidOperationException ex = Assert.Throws(
+ () => JsonSerializer.Serialize(YesOrNoOrEmptyFlags.Yes, s_optionsWithStringEnumConverter));
+ Assert.Contains(expectedExceptionMessage, ex.Message);
+
+ ex = Assert.Throws(
+ () => JsonSerializer.Deserialize("\"y\"", s_optionsWithStringEnumConverter));
+ Assert.Contains(expectedExceptionMessage, ex.Message);
+ }
+
+ [Flags]
+ public enum YesOrNoOrEmptyFlags
+ {
+ [JsonStringEnumMemberName("y")]
+ Yes = 1,
+
+ [JsonStringEnumMemberName("n")]
+ No = 2,
+
+ [JsonStringEnumMemberName("")]
+ Empty = 4,
+ }
+
[Theory]
[InlineData("\"cAmElCaSe\"", EnumWithVaryingNamingPolicies.camelCase, JsonKnownNamingPolicy.SnakeCaseUpper)]
[InlineData("\"cAmElCaSe\"", EnumWithVaryingNamingPolicies.camelCase, JsonKnownNamingPolicy.SnakeCaseLower)]