From 004322c0d8bf12167f33c5ed17c57b7c830d92ef Mon Sep 17 00:00:00 2001 From: Heath Stewart Date: Tue, 24 Nov 2020 12:14:08 -0800 Subject: [PATCH] Escape curly braces in file names when logging Fixes #998 --- src/coverlet.core/Coverage.cs | 2 +- src/coverlet.core/Helpers/FileSystem.cs | 6 ++++++ .../Helpers/SourceRootTranslator.cs | 2 +- .../Instrumentation/Instrumenter.cs | 7 ++++--- .../Helpers/FileSystemTests.cs | 20 +++++++++++++++++++ 5 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 test/coverlet.core.tests/Helpers/FileSystemTests.cs diff --git a/src/coverlet.core/Coverage.cs b/src/coverlet.core/Coverage.cs index d64290b43..92d84273e 100644 --- a/src/coverlet.core/Coverage.cs +++ b/src/coverlet.core/Coverage.cs @@ -107,7 +107,7 @@ public CoveragePrepareResult PrepareModules() Array.ForEach(_excludeFilters ?? Array.Empty(), filter => _logger.LogVerbose($"Excluded module filter '{filter}'")); Array.ForEach(_includeFilters ?? Array.Empty(), filter => _logger.LogVerbose($"Included module filter '{filter}'")); - Array.ForEach(_excludedSourceFiles ?? Array.Empty(), filter => _logger.LogVerbose($"Excluded source files filter '{filter}'")); + Array.ForEach(_excludedSourceFiles ?? Array.Empty(), filter => _logger.LogVerbose($"Excluded source files filter '{FileSystem.EscapeFileName(filter)}'")); _excludeFilters = _excludeFilters?.Where(f => _instrumentationHelper.IsValidFilterExpression(f)).ToArray(); _includeFilters = _includeFilters?.Where(f => _instrumentationHelper.IsValidFilterExpression(f)).ToArray(); diff --git a/src/coverlet.core/Helpers/FileSystem.cs b/src/coverlet.core/Helpers/FileSystem.cs index 6d72fd920..7213d3b4e 100644 --- a/src/coverlet.core/Helpers/FileSystem.cs +++ b/src/coverlet.core/Helpers/FileSystem.cs @@ -53,5 +53,11 @@ public string[] ReadAllLines(string path) { return File.ReadAllLines(path); } + + // Escape format characters in file names + internal static string EscapeFileName(string fileName) + { + return fileName?.Replace("{", "{{").Replace("}", "}}"); + } } } diff --git a/src/coverlet.core/Helpers/SourceRootTranslator.cs b/src/coverlet.core/Helpers/SourceRootTranslator.cs index 00aab2720..5d6c43da0 100644 --- a/src/coverlet.core/Helpers/SourceRootTranslator.cs +++ b/src/coverlet.core/Helpers/SourceRootTranslator.cs @@ -98,7 +98,7 @@ public string ResolveFilePath(string originalFileName) if (_fileSystem.Exists(pathToCheck = Path.GetFullPath(originalFileName.Replace(mapping.Key, srm.OriginalPath)))) { (_resolutionCacheFiles ??= new Dictionary()).Add(originalFileName, pathToCheck); - _logger.LogVerbose($"Mapping resolved: '{originalFileName}' -> '{pathToCheck}'"); + _logger.LogVerbose($"Mapping resolved: '{FileSystem.EscapeFileName(originalFileName)}' -> '{FileSystem.EscapeFileName(pathToCheck)}'"); return pathToCheck; } } diff --git a/src/coverlet.core/Instrumentation/Instrumenter.cs b/src/coverlet.core/Instrumentation/Instrumenter.cs index e74dc051d..db021745e 100644 --- a/src/coverlet.core/Instrumentation/Instrumenter.cs +++ b/src/coverlet.core/Instrumentation/Instrumenter.cs @@ -9,6 +9,7 @@ using Coverlet.Core.Instrumentation.Reachability; using Coverlet.Core.Abstractions; using Coverlet.Core.Attributes; +using Coverlet.Core.Helpers; using Coverlet.Core.Symbols; using Microsoft.Extensions.FileSystemGlobbing; using Mono.Cecil; @@ -110,7 +111,7 @@ public bool CanInstrument() } else { - _logger.LogVerbose($"Unable to instrument module: {_module}, embedded pdb without local source files, [{firstNotFoundDocument}]"); + _logger.LogVerbose($"Unable to instrument module: {_module}, embedded pdb without local source files, [{FileSystem.EscapeFileName(firstNotFoundDocument)}]"); return false; } } @@ -122,7 +123,7 @@ public bool CanInstrument() } else { - _logger.LogVerbose($"Unable to instrument module: {_module}, pdb without local source files, [{firstNotFoundDocument}]"); + _logger.LogVerbose($"Unable to instrument module: {_module}, pdb without local source files, [{FileSystem.EscapeFileName(firstNotFoundDocument)}]"); return false; } } @@ -159,7 +160,7 @@ public InstrumenterResult Instrument() { foreach (string sourceFile in _excludedSourceFiles) { - _logger.LogVerbose($"Excluded source file: '{sourceFile}'"); + _logger.LogVerbose($"Excluded source file: '{FileSystem.EscapeFileName(sourceFile)}'"); } } diff --git a/test/coverlet.core.tests/Helpers/FileSystemTests.cs b/test/coverlet.core.tests/Helpers/FileSystemTests.cs new file mode 100644 index 000000000..618a94f89 --- /dev/null +++ b/test/coverlet.core.tests/Helpers/FileSystemTests.cs @@ -0,0 +1,20 @@ +using Coverlet.Core.Helpers; +using Xunit; + +namespace Coverlet.Core.Helpers.Tests +{ + public class FileSystemTests + { + [Theory] + [InlineData(null, null)] + [InlineData("", "")] + [InlineData("filename.cs", "filename.cs")] + [InlineData("filename{T}.cs", "filename{{T}}.cs")] + public void TestEscapeFileName(string fileName, string expected) + { + var actual = FileSystem.EscapeFileName(fileName); + + Assert.Equal(expected, actual); + } + } +} \ No newline at end of file