diff --git a/src/TraceClient/TraceClient.cs b/src/TraceClient/TraceClient.cs index 06241b6..4b48f7a 100644 --- a/src/TraceClient/TraceClient.cs +++ b/src/TraceClient/TraceClient.cs @@ -76,7 +76,8 @@ public sealed class TraceClient : IDisposable /// The most tags the server accepts on one report. public const int MaxTags = 32; - /// The longest application, name, tag key or tag value the server accepts, in UTF-16 chars. + /// The longest application, name, tag key or tag value the server accepts, in UTF-16 chars. + /// The program's version and installation ID are tag values too, so the constructor rejects either past it. public const int MaxLength = 255; /// Environment variable that turns reporting off: off, false, 0, no. @@ -122,9 +123,10 @@ public sealed class TraceClient : IDisposable /// , reporting to the trace server at /// . Throws only for a /// missing or malformed , a missing - /// , or a missing or - /// one longer than characters -- programming errors, - /// not runtime ones. + /// , a missing or + /// one longer than characters, or an + /// longer than characters -- + /// programming errors, not runtime ones. /// /// The trace server, e.g. https://trace.danielstephenson.dev. /// The program's name, exactly as its key was issued for. diff --git a/tests/TraceClient.Tests/TraceClientTest.cs b/tests/TraceClient.Tests/TraceClientTest.cs index 6dbd83f..92b6300 100644 --- a/tests/TraceClient.Tests/TraceClientTest.cs +++ b/tests/TraceClient.Tests/TraceClientTest.cs @@ -453,6 +453,38 @@ public void Json_RejectsATagKeyLongerThanTheLimitAndNamesOnlyItsStart() Assert.Null(body); } + [Fact] + public void Json_RejectsANameLongerThanTheLimitButNotOneAtIt() + { + string longest = new string('n', TraceClient.MaxLength); + string tooLong = new string('n', TraceClient.MaxLength + 1); + + string problem = TraceClient.Json("App", tooLong, null, null, out string rejected); + + Assert.Equal("name longer than " + TraceClient.MaxLength + " characters", problem); + Assert.Null(rejected); + Assert.Null(TraceClient.Json("App", longest, null, null, out string accepted)); + Assert.Contains(longest, accepted); + } + + [Fact] + public void Json_RejectsATagValueLongerThanTheLimitAndNamesItsKey() + { + // The reason names the key, not the value: the value is what ran + // away, and the key is what the program can find in its source. + string tooLongValue = new string('v', TraceClient.MaxLength + 1); + string longestValue = new string('v', TraceClient.MaxLength); + + string problem = TraceClient.Json("App", "n", null, + new Dictionary { { "level", tooLongValue } }, out string body); + + Assert.Equal("tag level longer than " + TraceClient.MaxLength + " characters", problem); + Assert.Null(body); + Assert.Null(TraceClient.Json("App", "n", null, + new Dictionary { { "level", longestValue } }, out string accepted)); + Assert.Contains("\"level\":\"" + longestValue + "\"", accepted); + } + [Fact] public void Quote_EscapesCarriageReturnAndEveryOtherControlCharacter() {