From 5ac95019bbb5bdeb3a35c68368d9c2045cc48e44 Mon Sep 17 00:00:00 2001 From: Vijay Misal Date: Mon, 10 Aug 2026 21:39:42 +0530 Subject: [PATCH] Fix IndexOutOfRangeException when applying naming convention to empty string INamingConvention.Apply("") throws System.IndexOutOfRangeException for the camel/pascal/hyphenated/underscored conventions because ToCamelOrPascalCase and FromCamelCase in StringExtensions.cs index the first character (text[0] / str[0]) without checking for an empty input. Add a short-circuit that returns the input unchanged when it is null or empty, matching the suggested fix in the issue report. Added a theory test covering all built-in naming conventions with an empty string input. Fixes #1114 --- .../Serialization/NamingConventionTests.cs | 17 +++++++++++++++++ .../Serialization/Utilities/StringExtensions.cs | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/YamlDotNet.Test/Serialization/NamingConventionTests.cs b/YamlDotNet.Test/Serialization/NamingConventionTests.cs index 9f22c60a1..dca5f434b 100644 --- a/YamlDotNet.Test/Serialization/NamingConventionTests.cs +++ b/YamlDotNet.Test/Serialization/NamingConventionTests.cs @@ -19,6 +19,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +using System.Collections.Generic; using FluentAssertions; using Xunit; using YamlDotNet.Serialization; @@ -77,6 +78,22 @@ public void AppliesLowerCaseConvention(string expectedName, string input) ShouldApplyConventionGiven(input, expectedName, LowerCaseNamingConvention.Instance); } + public static IEnumerable AllNamingConventions() + { + yield return new object[] { CamelCaseNamingConvention.Instance }; + yield return new object[] { PascalCaseNamingConvention.Instance }; + yield return new object[] { HyphenatedNamingConvention.Instance }; + yield return new object[] { UnderscoredNamingConvention.Instance }; + yield return new object[] { LowerCaseNamingConvention.Instance }; + } + + [Theory] + [MemberData(nameof(AllNamingConventions))] + public void ApplyingConventionToEmptyStringReturnsEmptyString(INamingConvention convention) + { + convention.Apply(string.Empty).Should().Be(string.Empty); + } + private void ShouldApplyConventionGiven(string input, string expectedName, INamingConvention convention) { convention.Apply(input).Should().Be(expectedName); diff --git a/YamlDotNet/Serialization/Utilities/StringExtensions.cs b/YamlDotNet/Serialization/Utilities/StringExtensions.cs index 4fcf9dd5c..75276660c 100644 --- a/YamlDotNet/Serialization/Utilities/StringExtensions.cs +++ b/YamlDotNet/Serialization/Utilities/StringExtensions.cs @@ -32,6 +32,11 @@ internal static class StringExtensions { private static string ToCamelOrPascalCase(string str, Func firstLetterTransform) { + if (string.IsNullOrEmpty(str)) + { + return str; + } + var text = Regex.Replace(str, "([_\\-])(?[a-z])", match => match.Groups["char"].Value.ToUpperInvariant(), RegexOptions.IgnoreCase); return firstLetterTransform(text[0]) + text.Substring(1); } @@ -70,6 +75,11 @@ public static string ToPascalCase(this string str) /// Converted string public static string FromCamelCase(this string str, string separator) { + if (string.IsNullOrEmpty(str)) + { + return str; + } + // Ensure first letter is always lowercase str = char.ToLower(str[0], CultureInfo.InvariantCulture) + str.Substring(1);