From ad68784bf910c8f3980baff802ec4350d9b44c26 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Tue, 26 May 2026 12:30:31 -0600 Subject: [PATCH] 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> --- .../Update/BindingRedirectsTests.cs | 52 +++++++++++++++++++ .../Updater/BindingRedirectManager.cs | 11 ++-- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs index 69cae8b584f..f9cf1bdd6d5 100644 --- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs @@ -205,6 +205,58 @@ await VerifyBindingRedirectsAsync( ); } + [Fact] + public async Task MalformedConfigFileThrowsUnparseableFileException() + { + var projectContents = """ + + + + v4.5 + + + + + + + packages\Some.Package.2.0.0\lib\net45\Some.Package.dll + True + + + + + """; + var configContents = """ + + + + + + + + + + + + + """; + + using var tempDir = new TemporaryDirectory(); + var projectFileName = "project.csproj"; + var projectFilePath = Path.Combine(tempDir.DirectoryPath, projectFileName); + var configFilePath = Path.Combine(tempDir.DirectoryPath, "app.config"); + + File.WriteAllText(projectFilePath, projectContents); + File.WriteAllText(configFilePath, configContents); + + var projectBuildFile = ProjectBuildFile.Open(tempDir.DirectoryPath, projectFilePath); + var exception = await Assert.ThrowsAsync( + () => BindingRedirectManager.UpdateBindingRedirectsAsync(tempDir.DirectoryPath, projectBuildFile, "Some.Package", "2.0.0").AsTask()); + Assert.Equal(configFilePath.NormalizePathToUnix(), exception.FilePath); + Assert.Contains("Error loading binding redirect configuration", exception.Message); + } + private static async Task VerifyBindingRedirectsAsync(string projectContents, string configContents, string expectedConfigContents, string updatedPackageName, string updatedPackageVersion, string configFileName = "app.config") { using var tempDir = new TemporaryDirectory(); diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs index 3e3bf39fef8..822bb613614 100644 --- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs @@ -1,4 +1,5 @@ using System.Collections.Immutable; +using System.Xml; using System.Xml.Linq; using Microsoft.Language.Xml; @@ -154,7 +155,7 @@ private static string AddBindingRedirects(ConfigurationFile configFile, IEnumera } // Get the configuration file - var document = GetConfiguration(configFile.Content); + var document = GetConfiguration(configFile.Content, configFile.Path); // Get the runtime element var runtime = document.Root?.Element("runtime"); @@ -211,15 +212,19 @@ private static string AddBindingRedirects(ConfigurationFile configFile, IEnumera document.ToString() ); - static XDocument GetConfiguration(string configFileContent) + static XDocument GetConfiguration(string configFileContent, string configFilePath) { try { return XDocument.Parse(configFileContent, LoadOptions.PreserveWhitespace); } + catch (XmlException ex) + { + throw new UnparseableFileException($"Error loading binding redirect configuration: {ex.Message}", configFilePath); + } catch (Exception ex) { - throw new InvalidOperationException("Error loading binging redirect configuration", ex); + throw new InvalidOperationException("Error loading binding redirect configuration", ex); } }