Skip to content

Commit 95bb2aa

Browse files
Escape Param data for the exporters (#2135)
* Rename: Escape -> EscapeCommandLine * Escape special characters for the all exporters
1 parent 7f9590a commit 95bb2aa

File tree

7 files changed

+48
-8
lines changed

7 files changed

+48
-8
lines changed

src/BenchmarkDotNet/Extensions/StringAndTextExtensions.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ private static readonly Lazy<Dictionary<string, string>> InvalidFileNameCharacte
1616
internal static string ToLowerCase(this bool value) => value ? "true" : "false"; // to avoid .ToString().ToLower() allocation
1717

1818
// source: https://stackoverflow.com/a/12364234/5852046
19-
internal static string Escape(this string cliArg)
19+
internal static string EscapeCommandLine(this string cliArg)
2020
{
2121
if (string.IsNullOrEmpty(cliArg))
2222
return cliArg;
@@ -27,6 +27,16 @@ internal static string Escape(this string cliArg)
2727
return value;
2828
}
2929

30+
/// <summary>
31+
/// Escapes UNICODE control characters
32+
/// </summary>
33+
/// <param name="str">string to escape</param>
34+
/// <param name="quote">True to put (double) quotes around the string literal</param>
35+
internal static string EscapeSpecialCharacters(this string str, bool quote)
36+
{
37+
return Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(str, quote);
38+
}
39+
3040
/// <summary>
3141
/// replaces all invalid file name chars with their number representation
3242
/// </summary>

src/BenchmarkDotNet/Parameters/ParameterInstance.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ private string ToDisplayText(CultureInfo cultureInfo, int maxParameterColumnWidt
4444
case null:
4545
return NullParameterTextRepresentation;
4646
case IParam parameter:
47-
return Trim(parameter.DisplayText, maxParameterColumnWidth);
47+
return Trim(parameter.DisplayText, maxParameterColumnWidth).EscapeSpecialCharacters(false);
4848
case IFormattable formattable:
49-
return Trim(formattable.ToString(null, cultureInfo), maxParameterColumnWidth);
49+
return Trim(formattable.ToString(null, cultureInfo), maxParameterColumnWidth).EscapeSpecialCharacters(false);
5050
// no trimming for types!
5151
case Type type:
5252
return type.IsNullable() ? $"{Nullable.GetUnderlyingType(type).GetDisplayName()}?" : type.GetDisplayName();
5353
default:
54-
return Trim(value.ToString(), maxParameterColumnWidth);
54+
return Trim(value.ToString(), maxParameterColumnWidth).EscapeSpecialCharacters(false);
5555
}
5656
}
5757

src/BenchmarkDotNet/Running/BenchmarkId.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public BenchmarkId(int value, BenchmarkCase benchmarkCase)
3030

3131
public override int GetHashCode() => Value;
3232

33-
public string ToArguments() => $"--benchmarkName {FullBenchmarkName.Escape()} --job {JobId.Escape()} --benchmarkId {Value}";
33+
public string ToArguments() => $"--benchmarkName {FullBenchmarkName.EscapeCommandLine()} --job {JobId.EscapeCommandLine()} --benchmarkId {Value}";
3434

3535
public string ToArguments(string fromBenchmark, string toBenchmark) => $"{AnonymousPipesHost.AnonymousPipesDescriptors} {fromBenchmark} {toBenchmark} {ToArguments()}";
3636

src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliExecutor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ private ExecuteResult Execute(BenchmarkCase benchmarkCase,
6969
var startInfo = DotNetCliCommandExecutor.BuildStartInfo(
7070
CustomDotNetCliPath,
7171
artifactsPaths.BinariesDirectoryPath,
72-
$"{executableName.Escape()} {benchmarkId.ToArguments(inputFromBenchmark.GetClientHandleAsString(), acknowledgments.GetClientHandleAsString())}",
72+
$"{executableName.EscapeCommandLine()} {benchmarkId.ToArguments(inputFromBenchmark.GetClientHandleAsString(), acknowledgments.GetClientHandleAsString())}",
7373
redirectStandardOutput: true,
7474
redirectStandardInput: false,
7575
redirectStandardError: false); // #1629

src/BenchmarkDotNet/Toolchains/Roslyn/Generator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ protected override void GenerateBuildScript(BuildPartition buildPartition, Artif
3838
list.Add("/unsafe");
3939
list.Add("/deterministic");
4040
list.Add("/platform:" + buildPartition.Platform.ToConfig());
41-
list.Add("/appconfig:" + artifactsPaths.AppConfigPath.Escape());
42-
var references = GetAllReferences(buildPartition.RepresentativeBenchmarkCase).Select(assembly => assembly.Location.Escape());
41+
list.Add("/appconfig:" + artifactsPaths.AppConfigPath.EscapeCommandLine());
42+
var references = GetAllReferences(buildPartition.RepresentativeBenchmarkCase).Select(assembly => assembly.Location.EscapeCommandLine());
4343
list.Add("/reference:" + string.Join(",", references));
4444
list.Add(Path.GetFileName(artifactsPaths.ProgramCodePath));
4545

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
=== Escape_ParamsAndArguments ===
2+
3+
BenchmarkDotNet=v0.10.x-mock, OS=Microsoft Windows NT 10.0.x.mock, VM=Hyper-V
4+
MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores
5+
Frequency=2531248 Hz, Resolution=395.0620 ns, Timer=TSC
6+
[Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION
7+
DefaultJob : extra output line
8+
9+
10+
Method | StringParam | charArg | Mean | Error | StdDev |
11+
------- |------------ |-------- |---------:|--------:|--------:|
12+
Foo | \t | \t | 102.0 ns | 6.09 ns | 1.58 ns | ^
13+
Foo | \t | \n | 202.0 ns | 6.09 ns | 1.58 ns | ^
14+
Bar | \t | ? | 302.0 ns | 6.09 ns | 1.58 ns | ^
15+
Foo | \n | \t | 402.0 ns | 6.09 ns | 1.58 ns | ^
16+
Foo | \n | \n | 502.0 ns | 6.09 ns | 1.58 ns | ^
17+
Bar | \n | ? | 602.0 ns | 6.09 ns | 1.58 ns | ^
18+
19+
Errors: 0

tests/BenchmarkDotNet.Tests/Exporters/MarkdownExporterApprovalTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,17 @@ public class Invalid_TwoJobBaselines
255255
[Benchmark] public void Foo() {}
256256
[Benchmark] public void Bar() {}
257257
}
258+
259+
/* Escape Params */
260+
261+
public class Escape_ParamsAndArguments
262+
{
263+
[Params("\t", "\n"), UsedImplicitly] public string StringParam;
264+
265+
[Arguments('\t')] [Arguments('\n')]
266+
[Benchmark] public void Foo(char charArg) {}
267+
[Benchmark] public void Bar() {}
268+
}
258269
}
259270
}
260271
}

0 commit comments

Comments
 (0)