[HLE] Make guest printf formatting locale-invariant (#271)

This commit is contained in:
kuba
2026-07-16 18:39:48 +02:00
committed by GitHub
parent 16a2131b67
commit e10efa3ae1
2 changed files with 25 additions and 11 deletions
@@ -4037,7 +4037,7 @@ public static partial class KernelMemoryCompatExports
_ => unchecked((int)argumentSource.NextGpArg()) _ => unchecked((int)argumentSource.NextGpArg())
}; };
var formatted = value.ToString(); var formatted = value.ToString(CultureInfo.InvariantCulture);
if (showSign && value >= 0) if (showSign && value >= 0)
formatted = "+" + formatted; formatted = "+" + formatted;
else if (spaceForSign && value >= 0) else if (spaceForSign && value >= 0)
@@ -4057,7 +4057,7 @@ public static partial class KernelMemoryCompatExports
_ => (uint)argumentSource.NextGpArg() _ => (uint)argumentSource.NextGpArg()
}; };
var formatted = value.ToString(); var formatted = value.ToString(CultureInfo.InvariantCulture);
sb.Append(PadString(formatted, width, leftAlign, padWithZero && !leftAlign)); sb.Append(PadString(formatted, width, leftAlign, padWithZero && !leftAlign));
} }
break; break;
@@ -4074,8 +4074,8 @@ public static partial class KernelMemoryCompatExports
}; };
var formatted = specifier == 'x' var formatted = specifier == 'x'
? value.ToString("x") ? value.ToString("x", CultureInfo.InvariantCulture)
: value.ToString("X"); : value.ToString("X", CultureInfo.InvariantCulture);
if (alternateForm && value != 0) if (alternateForm && value != 0)
formatted = specifier == 'x' ? "0x" + formatted : "0X" + formatted; formatted = specifier == 'x' ? "0x" + formatted : "0X" + formatted;
@@ -4179,7 +4179,10 @@ public static partial class KernelMemoryCompatExports
var formatStr = precision >= 0 var formatStr = precision >= 0
? $"{{0:{specifier}{precision}}}" ? $"{{0:{specifier}{precision}}}"
: $"{{0:{specifier}}}"; : $"{{0:{specifier}}}";
var formatted = string.Format(formatStr, value); var formatted = string.Format(
CultureInfo.InvariantCulture,
formatStr,
value);
if (showSign && value >= 0) if (showSign && value >= 0)
formatted = "+" + formatted; formatted = "+" + formatted;
@@ -3,6 +3,7 @@
using SharpEmu.HLE; using SharpEmu.HLE;
using SharpEmu.Libs.Kernel; using SharpEmu.Libs.Kernel;
using System.Globalization;
using System.Text; using System.Text;
using Xunit; using Xunit;
@@ -44,12 +45,22 @@ public sealed class KernelMemoryCompatExportsTests
unchecked((ulong)BitConverter.DoubleToInt64Bits(0.5576)), unchecked((ulong)BitConverter.DoubleToInt64Bits(0.5576)),
0); 0);
var result = KernelMemoryCompatExports.Sprintf(context); var previousCulture = CultureInfo.CurrentCulture;
try
{
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("es-ES");
Assert.Equal(0, result); var result = KernelMemoryCompatExports.Sprintf(context);
Assert.Equal(6UL, context[CpuRegister.Rax]);
Span<byte> output = stackalloc byte[7]; Assert.Equal(0, result);
Assert.True(memory.TryRead(destinationAddress, output)); Assert.Equal(6UL, context[CpuRegister.Rax]);
Assert.Equal("0.5576\0", Encoding.UTF8.GetString(output)); Span<byte> output = stackalloc byte[7];
Assert.True(memory.TryRead(destinationAddress, output));
Assert.Equal("0.5576\0", Encoding.UTF8.GetString(output));
}
finally
{
CultureInfo.CurrentCulture = previousCulture;
}
} }
} }