Skip to content

Commit

Permalink
Fix files kept in use in XslTransformation
Browse files Browse the repository at this point in the history
Following #6863, the created XmlReader is no longer responsible for its
underlying stream. This can cause the build process to hold on to the
processed file, preventing its removal. This can especially be a problem
when the transformation is in fact aimed at the input file itself, where
we want to create the transformed file, then move it to the original.
  • Loading branch information
lanfeust69 committed Oct 14, 2021
1 parent bbcce1d commit 5b67e83
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
36 changes: 35 additions & 1 deletion src/Tasks.UnitTests/XslTransformation_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Text.RegularExpressions;
using System.Xml.Xsl;
using System.Xml;
using Shouldly;
using Xunit;

namespace Microsoft.Build.UnitTests
Expand Down Expand Up @@ -386,7 +387,7 @@ public void OutputTest()
/// Setting correct "Parameter" parameters for Xsl.
/// </summary>
[Fact]
public void XsltParamatersCorrect()
public void XsltParametersCorrect()
{
string dir;
TaskItem[] xmlPaths;
Expand Down Expand Up @@ -780,6 +781,39 @@ public void OutputFileCannotBeWritten()
CleanUp(dir);
}

/// <summary>
/// The files are not kept locked by the task
/// </summary>
[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;

Assert.True(t.Execute());
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);
}

/// <summary>
/// XslDocument that throws runtime exception.
/// </summary>
Expand Down
9 changes: 6 additions & 3 deletions src/Tasks/XslTransformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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]));
}
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 5b67e83

Please sign in to comment.