diff options
author | Alan McGovern <alan@xamarin.com> | 2014-01-16 00:17:10 +0400 |
---|---|---|
committer | Alan McGovern <alan@xamarin.com> | 2014-01-16 00:33:16 +0400 |
commit | 6d7e812d709e182810d64c51a4e2d1af25d8adfa (patch) | |
tree | 3f9a9f0c0479cd3f2b8e7a834314887658846cab /mcs/class | |
parent | 89fcde4fd1b96aa575741a799e305a50977e139b (diff) |
[Microsoft.Build.Engine] Fix the escaping/unescaping of FullPath metadata
It is incorrect to escape the FullPath metadata for a build item when
we invoke GetEvaluatedMetadata. If we do this we end up completely breaking
every file with a special character in it as things like this would always
fail as we'd pass an escaped path to the filesystem:
File.Exists (item.GetEvaluatedMetadata ("FullPath"))
The iOS designer encountered this issue when we added retina images
called "foo@2x.png" to our solution.
With tests.
Diffstat (limited to 'mcs/class')
3 files changed, 38 insertions, 8 deletions
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildItem.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildItem.cs index fc22d1f5631..86f14a1a797 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildItem.cs +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildItem.cs @@ -167,9 +167,7 @@ namespace Microsoft.Build.BuildEngine { { if (ReservedNameUtils.IsReservedMetadataName (metadataName)) { string metadata = ReservedNameUtils.GetReservedMetadata (FinalItemSpec, metadataName, evaluatedMetadata); - return string.Equals (metadataName, "fullpath", StringComparison.OrdinalIgnoreCase) - ? MSBuildUtils.Escape (metadata) - : metadata; + return MSBuildUtils.Unescape (metadata); } if (evaluatedMetadata.Contains (metadataName)) @@ -181,10 +179,7 @@ namespace Microsoft.Build.BuildEngine { public string GetMetadata (string metadataName) { if (ReservedNameUtils.IsReservedMetadataName (metadataName)) { - string metadata = ReservedNameUtils.GetReservedMetadata (FinalItemSpec, metadataName, unevaluatedMetadata); - return string.Equals (metadataName, "fullpath", StringComparison.OrdinalIgnoreCase) - ? MSBuildUtils.Escape (metadata) - : metadata; + return ReservedNameUtils.GetReservedMetadata (FinalItemSpec, metadataName, unevaluatedMetadata); } else if (unevaluatedMetadata.Contains (metadataName)) return (string) unevaluatedMetadata [metadataName]; else diff --git a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/BuildItemTest.cs b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/BuildItemTest.cs index e580d358ed0..918c3ff8ae2 100644 --- a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/BuildItemTest.cs +++ b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/BuildItemTest.cs @@ -285,6 +285,40 @@ namespace MonoTests.Microsoft.Build.BuildEngine { } [Test] + public void GetMetadata_UnescapedItemSpec () + { + string itemInclude = "a;b;c"; + string escapedItemInclude = Utilities.Escape (itemInclude); + + item = new BuildItem ("name", itemInclude); + Assert.IsTrue (item.GetMetadata ("FullPath").EndsWith (escapedItemInclude), "#1a"); + Assert.IsTrue (item.GetEvaluatedMetadata ("FullPath").EndsWith (itemInclude), "#1b"); + + Assert.AreEqual (itemInclude, item.GetMetadata ("FileName"), "#2b"); + Assert.AreEqual (itemInclude, item.GetEvaluatedMetadata ("FileName"), "#2b"); + + Assert.AreEqual (itemInclude, item.GetMetadata ("Identity"), "#3a"); + Assert.AreEqual (itemInclude, item.GetEvaluatedMetadata ("Identity"), "#3b"); + } + + [Test] + public void GetMetadata_EscapedItemSpec () + { + string itemInclude = "a;b;c"; + string escapedItemInclude = Utilities.Escape (itemInclude); + + item = new BuildItem ("name", escapedItemInclude); + Assert.IsTrue (item.GetMetadata ("FullPath").EndsWith (escapedItemInclude), "#1a"); + Assert.IsTrue (item.GetEvaluatedMetadata ("FullPath").EndsWith (itemInclude), "#1b"); + + Assert.AreEqual (escapedItemInclude, item.GetMetadata ("FileName"), "#2b"); + Assert.AreEqual (itemInclude, item.GetEvaluatedMetadata ("FileName"), "#2b"); + + Assert.AreEqual (escapedItemInclude, item.GetMetadata ("Identity"), "#3a"); + Assert.AreEqual ("a;b;c", item.GetEvaluatedMetadata ("Identity"), "#3b"); + } + + [Test] [ExpectedException (typeof (ArgumentNullException))] public void TestGetMetadata2 () { diff --git a/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs b/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs index f2712566d59..6789cfbd928 100644 --- a/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs +++ b/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs @@ -77,7 +77,8 @@ namespace Mono.XBuild.Utilities { switch (metadataName.ToLowerInvariant ()) { case "fullpath": - return Path.GetFullPath (itemSpec); + var unescapedItemSpec = MSBuildUtils.Unescape (itemSpec); + return MSBuildUtils.Escape (Path.GetFullPath (unescapedItemSpec)); case "rootdir": if (Path.IsPathRooted (itemSpec)) return Path.GetPathRoot (itemSpec); |