Skip to content

Commit ad68784

Browse files
brettfoCopilot
andcommitted
NuGet: Fix binding redirect XML parse error to report unparseable file
When updating binding redirects, a failure to parse the XML config file was throwing an InvalidOperationException which resulted in an unknown error being reported. This change catches XmlException specifically and throws UnparseableFileException instead, which is properly mapped to the dependency_file_not_parseable error type. Also fixes the typo 'binging' -> 'binding' in the error message. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent baa85eb commit ad68784

2 files changed

Lines changed: 60 additions & 3 deletions

File tree

nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,58 @@ await VerifyBindingRedirectsAsync(
205205
);
206206
}
207207

208+
[Fact]
209+
public async Task MalformedConfigFileThrowsUnparseableFileException()
210+
{
211+
var projectContents = """
212+
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
213+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
214+
<PropertyGroup>
215+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
216+
</PropertyGroup>
217+
<ItemGroup>
218+
<None Include="app.config" />
219+
</ItemGroup>
220+
<ItemGroup>
221+
<Reference Include="Some.Package, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
222+
<HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
223+
<Private>True</Private>
224+
</Reference>
225+
</ItemGroup>
226+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
227+
</Project>
228+
""";
229+
var configContents = """
230+
<configuration>
231+
<appSettings>
232+
<add key="SomeKey" value="SomeValue" />
233+
</appSettings
234+
<runtime>
235+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
236+
<dependentAssembly>
237+
<assemblyIdentity name="Some.Package" publicKeyToken="null" culture="neutral" />
238+
<bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
239+
</dependentAssembly>
240+
</assemblyBinding>
241+
</runtime>
242+
</configuration>
243+
""";
244+
245+
using var tempDir = new TemporaryDirectory();
246+
var projectFileName = "project.csproj";
247+
var projectFilePath = Path.Combine(tempDir.DirectoryPath, projectFileName);
248+
var configFilePath = Path.Combine(tempDir.DirectoryPath, "app.config");
249+
250+
File.WriteAllText(projectFilePath, projectContents);
251+
File.WriteAllText(configFilePath, configContents);
252+
253+
var projectBuildFile = ProjectBuildFile.Open(tempDir.DirectoryPath, projectFilePath);
254+
var exception = await Assert.ThrowsAsync<UnparseableFileException>(
255+
() => BindingRedirectManager.UpdateBindingRedirectsAsync(tempDir.DirectoryPath, projectBuildFile, "Some.Package", "2.0.0").AsTask());
256+
Assert.Equal(configFilePath.NormalizePathToUnix(), exception.FilePath);
257+
Assert.Contains("Error loading binding redirect configuration", exception.Message);
258+
}
259+
208260
private static async Task VerifyBindingRedirectsAsync(string projectContents, string configContents, string expectedConfigContents, string updatedPackageName, string updatedPackageVersion, string configFileName = "app.config")
209261
{
210262
using var tempDir = new TemporaryDirectory();

nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Immutable;
2+
using System.Xml;
23
using System.Xml.Linq;
34

45
using Microsoft.Language.Xml;
@@ -154,7 +155,7 @@ private static string AddBindingRedirects(ConfigurationFile configFile, IEnumera
154155
}
155156

156157
// Get the configuration file
157-
var document = GetConfiguration(configFile.Content);
158+
var document = GetConfiguration(configFile.Content, configFile.Path);
158159

159160
// Get the runtime element
160161
var runtime = document.Root?.Element("runtime");
@@ -211,15 +212,19 @@ private static string AddBindingRedirects(ConfigurationFile configFile, IEnumera
211212
document.ToString()
212213
);
213214

214-
static XDocument GetConfiguration(string configFileContent)
215+
static XDocument GetConfiguration(string configFileContent, string configFilePath)
215216
{
216217
try
217218
{
218219
return XDocument.Parse(configFileContent, LoadOptions.PreserveWhitespace);
219220
}
221+
catch (XmlException ex)
222+
{
223+
throw new UnparseableFileException($"Error loading binding redirect configuration: {ex.Message}", configFilePath);
224+
}
220225
catch (Exception ex)
221226
{
222-
throw new InvalidOperationException("Error loading binging redirect configuration", ex);
227+
throw new InvalidOperationException("Error loading binding redirect configuration", ex);
223228
}
224229
}
225230

0 commit comments

Comments
 (0)