diff --git a/src/LibHac/Util/StringUtils.cs b/src/LibHac/Util/StringUtils.cs index d554976b..b2ef7725 100644 --- a/src/LibHac/Util/StringUtils.cs +++ b/src/LibHac/Util/StringUtils.cs @@ -38,14 +38,15 @@ public static class StringUtils return i; } - public static int Strlcpy(Span dest, ReadOnlySpan source, int maxLen) + public static int Strlcpy(Span dest, ReadOnlySpan source, int size) { - int maxLenLocal = Math.Min(Math.Min(dest.Length, source.Length), maxLen); + int destSize = Math.Min(dest.Length, size); int i = 0; - if (maxLenLocal > 0) + if (destSize > 0) { - for (; i < maxLenLocal - 1 && source[i] != 0; i++) + int maxCopySize = Math.Min(destSize - 1, source.Length); + for (; i < maxCopySize && source[i] != 0; i++) { dest[i] = source[i]; } diff --git a/tests/LibHac.Tests/Util/StringUtilTests.cs b/tests/LibHac.Tests/Util/StringUtilTests.cs new file mode 100644 index 00000000..2fe040bc --- /dev/null +++ b/tests/LibHac.Tests/Util/StringUtilTests.cs @@ -0,0 +1,43 @@ +using System; +using System.Text; +using LibHac.Util; +using Xunit; + +namespace LibHac.Tests.Util; + +public class StringUtilTests +{ + [Theory] + [InlineData("abcdef", 3, 1, "", 6)] + [InlineData("abcdef", 3, 3, "ab", 6)] + [InlineData("abcdef", 3, 6, "ab", 6)] + [InlineData("abcdef", 6, 6, "abcde", 6)] + [InlineData("abcdef", 7, 6, "abcde", 6)] + [InlineData("abcdef", 7, 7, "abcdef", 6)] + [InlineData("abcdef", 10, 10, "abcdef", 6)] + public void Strlcpy_TestKnownInputs(string source, int destBufferSize, int size, string expected, int expectedReturnValue) + { + const byte paddingValue = (byte)'X'; + + byte[] src = Encoding.ASCII.GetBytes(source); + byte[] expectedBytes = Encoding.ASCII.GetBytes(expected); + byte[] dest = new byte[destBufferSize]; + dest.AsSpan().Fill(paddingValue); + + int returnValue = StringUtils.Strlcpy(dest, src, size); + + Assert.Equal(expectedReturnValue, returnValue); + + for (int i = 0; i < expectedBytes.Length; i++) + { + Assert.Equal(expectedBytes[i], dest[i]); + } + + Assert.Equal(0, dest[expectedBytes.Length]); + + for (int i = expectedBytes.Length + 1; i < dest.Length; i++) + { + Assert.Equal(paddingValue, dest[i]); + } + } +} \ No newline at end of file