From 827e39dbe90e1b6ec5f29c82534bd8894306be95 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 31 Jan 2017 10:55:07 -0800 Subject: [PATCH] MaybeAdjustFilePath should not collapse multiple slashes This ends up destroying data that contains double slashes, like URLs Resolves #1622 --- src/Shared/FileUtilities.cs | 4 +- .../EvaluatorFileNormalization_Tests.cs | 98 +++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/XMakeBuildEngine/UnitTests/Evaluation/EvaluatorFileNormalization_Tests.cs diff --git a/src/Shared/FileUtilities.cs b/src/Shared/FileUtilities.cs index e124863a3ac..647841369fa 100644 --- a/src/Shared/FileUtilities.cs +++ b/src/Shared/FileUtilities.cs @@ -413,8 +413,8 @@ internal static string MaybeAdjustFilePath(string value) return value; } - // For Unix-like systems, we may want to convert backslashes to slashes - string newValue = Regex.Replace(value, @"[\\/]+", "/"); + // For Unix-like systems, we want to convert backslashes to slashes + string newValue = value.ToSlash(); string quote = string.Empty; // Find the part of the name we want to check, that is remove quotes, if present diff --git a/src/XMakeBuildEngine/UnitTests/Evaluation/EvaluatorFileNormalization_Tests.cs b/src/XMakeBuildEngine/UnitTests/Evaluation/EvaluatorFileNormalization_Tests.cs new file mode 100644 index 00000000000..86b0275979b --- /dev/null +++ b/src/XMakeBuildEngine/UnitTests/Evaluation/EvaluatorFileNormalization_Tests.cs @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +//----------------------------------------------------------------------- +// +// Tests for evaluation +//----------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading; +using System.Xml; + +using Microsoft.Build.Collections; +using Microsoft.Build.Construction; +using Microsoft.Build.Evaluation; +using Microsoft.Build.Execution; +using Microsoft.Build.Framework; +using Microsoft.Build.Shared; +using Xunit; + +using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException; +using ProjectHelpers = Microsoft.Build.UnitTests.BackEnd.ProjectHelpers; + +namespace Microsoft.Build.UnitTests.Evaluation +{ + /// + /// Tests mainly for how evaluation normalizes input for cross-platform paths + /// + public class EvaluatorFileNormalization_Tests : IDisposable + { + public EvaluatorFileNormalization_Tests() + { + ProjectCollection.GlobalProjectCollection.UnloadAllProjects(); + GC.Collect(); + } + + /// + /// Cleanup + /// + public void Dispose() + { + ProjectCollection.GlobalProjectCollection.UnloadAllProjects(); + GC.Collect(); + } + + /// + /// Basic verification -- with TreatAsLocalProperty set, but to a different property than is being passed as a global, the + /// global property overrides the local property. + /// + [Fact] + public void MultipleForwardSlashesShouldNotGetCollapsedWhenPathLooksLikeUnixPath() + { + string content = ObjectModelHelpers.CleanupFileContents(@" + + +

/tmp/a//x\\c;ba://

+
+ + + + + + + + + + + + + +
"); + + + IDictionary globalProperties = new Dictionary(StringComparer.OrdinalIgnoreCase); + globalProperties.Add("GP", @"/tmp/a//x\\c;ba://"); + + Project project = new Project(XmlReader.Create(new StringReader(content)), globalProperties, null); + + MockLogger logger = new MockLogger(); + bool result = project.Build(logger); + Assert.Equal(true, result); + + var expectedString = NativeMethodsShared.IsWindows ? @"/tmp/a//x\\c;ba://" : @"/tmp/a//x//c;ba://"; + + logger.AssertLogContains($"GP[{expectedString}]"); + logger.AssertLogContains($"P[{expectedString}]"); + logger.AssertLogContains($"I[{expectedString}]"); + logger.AssertLogContains($"T[{expectedString}]"); + + Assert.Equal(expectedString, project.GetPropertyValue("GP")); + Assert.Equal(expectedString, project.GetPropertyValue("P")); + Assert.Equal(expectedString, string.Join(";", project.Items.Select(i => i.EvaluatedInclude))); + } + } +}