From 5304aab4aa386dac9ef8026270d156d1682988dd Mon Sep 17 00:00:00 2001 From: Carol Wang Date: Mon, 11 Aug 2025 17:02:16 +0800 Subject: [PATCH] System.Runtime.Serialization.Xml: throw SerializationException on malformed prefix --- .../Serialization/XmlObjectSerializer.cs | 8 ++++++ .../tests/DataContractSerializer.cs | 27 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializer.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializer.cs index 3dcd6c7886b417..2f6d9bc1761752 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializer.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializer.cs @@ -363,6 +363,10 @@ internal virtual bool InternalIsStartObject(XmlReaderDelegator reader) { throw XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorDeserializing, GetDeserializeType(), ex), ex); } + catch (ArgumentException ex) + { + throw XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorDeserializing, GetDeserializeType(), ex), ex); + } } [RequiresDynamicCode(DataContract.SerializerAOTWarning)] @@ -383,6 +387,10 @@ internal bool IsStartObjectHandleExceptions(XmlReaderDelegator reader) { throw XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorIsStartObject, GetDeserializeType(), ex), ex); } + catch (ArgumentException ex) + { + throw XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorIsStartObject, GetDeserializeType(), ex), ex); + } } internal static bool IsRootXmlAny(XmlDictionaryString? rootName, DataContract contract) diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs index 7f5599020944f7..929e92786aab83 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs @@ -4517,6 +4517,23 @@ public static void DCS_ReadObject_XmlDictionaryReaderMaxStringContentLengthExcee Assert.Throws(() => { dcs.ReadObject(reader); }); } + [Fact] + public static void DCS_ReadObject_MalformedPrefix_EmptyLocalName_ThrowsSerializationException() + { + // Regression for https://github.com/dotnet/runtime/issues/1409 + // Uses the original repro payload that triggers an empty local-name via an unfinished prefixed element. + string xml = @"(() => serializer.ReadObject(stream)); + Assert.NotNull(ex.InnerException); + Assert.IsType(ex.InnerException); + Assert.Equal("name", ((ArgumentException)ex.InnerException).ParamName); + } + } + private static T DeserializeString(string stringToDeserialize, bool shouldReportDeserializationExceptions = true, DataContractSerializerSettings settings = null, Func serializerFactory = null) { DataContractSerializer dcs; @@ -4574,3 +4591,13 @@ private static void TestObjectWithDifferentPayload(T value, string netcorePay SerializationTestTypes.ComparisonHelper.CompareRecursively(value, deserializedDesktopObject); } } + +// Test helper type +namespace CoreFX.Fuzz +{ + public class Program + { + [DataContract] + public class Obj { } + } +}