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