diff --git a/src/Tasks.UnitTests/XslTransformation_Tests.cs b/src/Tasks.UnitTests/XslTransformation_Tests.cs
index 5fc54d6dfcf..785bab86be5 100644
--- a/src/Tasks.UnitTests/XslTransformation_Tests.cs
+++ b/src/Tasks.UnitTests/XslTransformation_Tests.cs
@@ -13,6 +13,7 @@
using System.Text.RegularExpressions;
using System.Xml.Xsl;
using System.Xml;
+using Shouldly;
using Xunit;
namespace Microsoft.Build.UnitTests
@@ -386,7 +387,7 @@ public void OutputTest()
/// Setting correct "Parameter" parameters for Xsl.
///
[Fact]
- public void XsltParamatersCorrect()
+ public void XsltParametersCorrect()
{
string dir;
TaskItem[] xmlPaths;
@@ -780,6 +781,39 @@ public void OutputFileCannotBeWritten()
CleanUp(dir);
}
+ ///
+ /// The files are not kept locked by the task
+ ///
+ [Fact]
+ public void InputFilesDontLock()
+ {
+ string dir;
+ TaskItem[] xmlPaths;
+ TaskItem xslPath;
+ TaskItem[] outputPaths;
+ MockEngine engine;
+ Prepare(out dir, out xmlPaths, out xslPath, out _, out outputPaths, out _, out _, out engine);
+
+ // Test with files
+ {
+ XslTransformation t = new XslTransformation();
+ t.BuildEngine = engine;
+ t.XmlInputPaths = xmlPaths;
+ t.XslInputPath = xslPath;
+ t.OutputPaths = outputPaths;
+
+ t.Execute().ShouldBeTrue();
+ string xmlInputPath = xmlPaths[0].ItemSpec;
+ File.Delete(xmlInputPath); // this should succeed (file not locked by task)
+ File.Exists(xmlInputPath).ShouldBeFalse();
+ string xslInputPath = xslPath.ItemSpec;
+ File.Delete(xslInputPath); // this should succeed (file not locked by task)
+ File.Exists(xslInputPath).ShouldBeFalse();
+ }
+
+ CleanUp(dir);
+ }
+
///
/// XslDocument that throws runtime exception.
///
diff --git a/src/Tasks/XslTransformation.cs b/src/Tasks/XslTransformation.cs
index 3b8810be561..0f47a2edfe2 100644
--- a/src/Tasks/XslTransformation.cs
+++ b/src/Tasks/XslTransformation.cs
@@ -334,9 +334,9 @@ public XmlReader CreateReader(int itemPos)
{
if (XmlMode == XmlModes.XmlFile)
{
- return XmlReader.Create(new StreamReader(_data[itemPos]), null, _data[itemPos]);
+ return XmlReader.Create(new StreamReader(_data[itemPos]), new XmlReaderSettings { CloseInput = true }, _data[itemPos]);
}
- else // xmlModes.Xml
+ else // xmlModes.Xml
{
return XmlReader.Create(new StringReader(_data[itemPos]));
}
@@ -459,7 +459,10 @@ public XslCompiledTransform LoadXslt(bool useTrustedSettings)
_log.LogMessageFromResources(MessageImportance.Low, "XslTransform.UseTrustedSettings", _data);
}
- xslct.Load(new XPathDocument(XmlReader.Create(new StreamReader(_data), null, _data)), settings, new XmlUrlResolver());
+ using (XmlReader reader = XmlReader.Create(new StreamReader(_data), new XmlReaderSettings { CloseInput = true }, _data))
+ {
+ xslct.Load(new XPathDocument(reader), settings, new XmlUrlResolver());
+ }
break;
case XslModes.XsltCompiledDll:
#if FEATURE_COMPILED_XSL