From 6613043b9ce6ef668b9ca81bdc576918b406b969 Mon Sep 17 00:00:00 2001 From: Stephane Delcroix Date: Thu, 10 Apr 2025 13:50:21 +0200 Subject: [PATCH] [X] Protect some xmlns protect maui and x: xmlns from overloading. - fixes #28836 --- .../src/Build.Tasks/XmlTypeExtensions.cs | 24 +++++++++++++++++-- src/Controls/src/Xaml/XamlParser.cs | 13 ++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs b/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs index f11ac9eb3b88..92e0dc89eb29 100644 --- a/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs +++ b/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Xml; @@ -26,6 +27,16 @@ static IList GatherXmlnsDefinitionAttributes(ModuleDef if (ca.AttributeType.FullName == typeof(XmlnsDefinitionAttribute).FullName) { var attr = GetXmlnsDefinition(ca, asmDef); + //maui, and x: xmlns are protected + if (attr.XmlNamespace.StartsWith("http://schemas.microsoft.com/", StringComparison.OrdinalIgnoreCase) && + !attr.AssemblyName.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase) && + !attr.AssemblyName.StartsWith("System", StringComparison.OrdinalIgnoreCase) && + !attr.AssemblyName.StartsWith("mscorlib", StringComparison.OrdinalIgnoreCase)) + { + throw new BuildException(BuildExceptionCode.InvalidXaml, null, null, + $"Protected Xmlns {attr.XmlNamespace}. Can't add assembly {attr.AssemblyName}."); + } + xmlnsDefinitions.Add(attr); } } @@ -33,7 +44,7 @@ static IList GatherXmlnsDefinitionAttributes(ModuleDef } else { - // Use standard XF assemblies + // Use standard MAUI assemblies // (Should only happen in unit tests) var requiredAssemblies = new[] { typeof(XamlLoader).Assembly, @@ -42,7 +53,16 @@ static IList GatherXmlnsDefinitionAttributes(ModuleDef foreach (var assembly in requiredAssemblies) foreach (XmlnsDefinitionAttribute attribute in assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute), false)) { - attribute.AssemblyName = attribute.AssemblyName ?? assembly.FullName; + attribute.AssemblyName ??= assembly.FullName; + //maui, and x: xmlns are protected + if (attribute.XmlNamespace.StartsWith("http://schemas.microsoft.com/", StringComparison.OrdinalIgnoreCase) && + !attribute.AssemblyName.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase) && + !attribute.AssemblyName.StartsWith("System", StringComparison.OrdinalIgnoreCase) && + !attribute.AssemblyName.StartsWith("mscorlib", StringComparison.OrdinalIgnoreCase)) + { + throw new BuildException(BuildExceptionCode.InvalidXaml, null, null, + $"Protected Xmlns {attribute.XmlNamespace}. Can't add assembly {attribute.AssemblyName}."); } + xmlnsDefinitions.Add(attribute); } } diff --git a/src/Controls/src/Xaml/XamlParser.cs b/src/Controls/src/Xaml/XamlParser.cs index 242b98b19941..97ab6f9243ab 100644 --- a/src/Controls/src/Xaml/XamlParser.cs +++ b/src/Controls/src/Xaml/XamlParser.cs @@ -336,7 +336,7 @@ static IValueNode GetValueNode(object value, XmlReader reader) static void GatherXmlnsDefinitionAttributes() { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); - s_xmlnsDefinitions = new List(); + s_xmlnsDefinitions = []; foreach (var assembly in assemblies) { @@ -344,8 +344,17 @@ static void GatherXmlnsDefinitionAttributes() { foreach (XmlnsDefinitionAttribute attribute in assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute))) { + attribute.AssemblyName ??= assembly.FullName; + //maui, and x: xmlns are protected + if (attribute.XmlNamespace.StartsWith("http://schemas.microsoft.com/", StringComparison.Ordinal) && + !attribute.AssemblyName.StartsWith("Microsoft", StringComparison.Ordinal) && + !attribute.AssemblyName.StartsWith("System", StringComparison.Ordinal) && + !attribute.AssemblyName.StartsWith("mscorlib", StringComparison.Ordinal)) + { + Debug.WriteLine($"Can not overloadxmlns {attribute.XmlNamespace}. cause it's protected."); + continue; + } s_xmlnsDefinitions.Add(attribute); - attribute.AssemblyName = attribute.AssemblyName ?? assembly.FullName; } } catch (Exception ex)