diff --git a/Projects/Server.Tests/Tests/PropertyList/ObjectPropertyListSpanAddTests.cs b/Projects/Server.Tests/Tests/PropertyList/ObjectPropertyListSpanAddTests.cs index 408c53386..97e2d9f58 100644 --- a/Projects/Server.Tests/Tests/PropertyList/ObjectPropertyListSpanAddTests.cs +++ b/Projects/Server.Tests/Tests/PropertyList/ObjectPropertyListSpanAddTests.cs @@ -62,6 +62,21 @@ public class ObjectPropertyListSpanAddTests Assert.Equal((1070722, "Custom"), entries[0]); } + [Fact] + public void HashFormat_OnlyMarksIntegers() + { + // Integer {value:#} emits the cliloc marker "#". + var intList = new ObjectPropertyList(null); + intList.Add(1062028, $"{1043009:#}"); + Assert.Equal((1062028, "#1043009"), Decode(intList)[0]); + + // Float {value:#} is the standard '#' custom-numeric (digit-placeholder) format, not a cliloc + // marker -- so no leading '#'. + var dblList = new ObjectPropertyList(null); + dblList.Add(1062028, $"{42.0:#}"); + Assert.Equal((1062028, 42.0.ToString("#")), Decode(dblList)[0]); // "42" + } + [Fact] public void Add_TruncatesArgumentOverMaxLength() { diff --git a/Projects/Server/PropertyList/ObjectPropertyList.cs b/Projects/Server/PropertyList/ObjectPropertyList.cs index 73288f5e1..6404eccbd 100644 --- a/Projects/Server/PropertyList/ObjectPropertyList.cs +++ b/Projects/Server/PropertyList/ObjectPropertyList.cs @@ -384,9 +384,9 @@ public sealed class ObjectPropertyList : IPropertyList, IDisposable public void AppendFormatted(T value, string? format) { - // We support localization '#' cliloc formatter for custom property lists - // This allows someone to build an IPropertyList that creates HTML using the same syntax as LocalizationInterpolationHandler - if (format == "#") + // '#' marks an integer argument as a cliloc ("#"). Integers only -- a float/double/decimal + // '#' is the standard numeric format, not a cliloc marker. + if (format == "#" && value is int or uint or long or ulong or short or ushort or byte or sbyte) { AppendLiteral("#"); format = null;