diff --git a/src/Microsoft.DotNet.Wpf/cycle-breakers/PresentationFramework/PresentationFramework.cs b/src/Microsoft.DotNet.Wpf/cycle-breakers/PresentationFramework/PresentationFramework.cs index d73b585dd97..d208a672a21 100644 --- a/src/Microsoft.DotNet.Wpf/cycle-breakers/PresentationFramework/PresentationFramework.cs +++ b/src/Microsoft.DotNet.Wpf/cycle-breakers/PresentationFramework/PresentationFramework.cs @@ -11407,13 +11407,20 @@ public void CancelAsync() { } public static System.Xaml.XamlSchemaContext GetWpfSchemaContext() { throw null; } public static object Load(System.IO.Stream stream) { throw null; } public static object Load(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext) { throw null; } + public static object Load(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext, bool useRestrictiveXamlReader) { throw null; } public static object Load(System.Xaml.XamlReader reader) { throw null; } public static object Load(System.Xml.XmlReader reader) { throw null; } + public static object Load(System.Xml.XmlReader reader, bool useRestrictiveXamlReader) { throw null; } public object LoadAsync(System.IO.Stream stream) { throw null; } + public object LoadAsync(System.IO.Stream stream, bool useRestrictiveXamlReader) { throw null; } public object LoadAsync(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext) { throw null; } + public object LoadAsync(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext, bool useRestrictiveXamlReader) { throw null; } public object LoadAsync(System.Xml.XmlReader reader) { throw null; } + public object LoadAsync(System.Xml.XmlReader reader, bool useRestrictiveXamlReader) { throw null; } public static object Parse(string xamlText) { throw null; } + public static object Parse(string xamlText, bool useRestrictiveXamlReader) { throw null; } public static object Parse(string xamlText, System.Windows.Markup.ParserContext parserContext) { throw null; } + public static object Parse(string xamlText, System.Windows.Markup.ParserContext parserContext, bool useRestrictiveXamlReader) { throw null; } } public partial class XamlTypeMapper { diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/StickyNote/StickyNoteContentControl.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/StickyNote/StickyNoteContentControl.cs index a1379838bec..46e13529c57 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/StickyNote/StickyNoteContentControl.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/StickyNote/StickyNoteContentControl.cs @@ -234,7 +234,7 @@ public override void Load(XmlNode node) RichTextBox richTextBox = (RichTextBox)InnerControl; FlowDocument document = new FlowDocument(); - TextRange rtbRange = new TextRange(document.ContentStart, document.ContentEnd); + TextRange rtbRange = new TextRange(document.ContentStart, document.ContentEnd, useRestrictiveXamlXmlReader: true); using (MemoryStream buffer = new MemoryStream(Convert.FromBase64String(node.InnerText))) { rtbRange.Load(buffer, DataFormats.Xaml); diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextRange.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextRange.cs index 8336e7cbfa6..fcecbb166e3 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextRange.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextRange.cs @@ -65,6 +65,24 @@ public TextRange(TextPointer position1, TextPointer position2) : internal TextRange(ITextPointer position1, ITextPointer position2) : this(position1, position2, false /* ignoreTextUnitBoundaries */) { + } + + /// + /// Creates a new TextRange instance. + /// + /// + /// + /// TextPointer specifying the static end of the new TextRange. + /// + /// TextPointer specifying the dynamic end of the new TextRange. + /// + /// + /// Boolean flag. False by default, set to true to disable external xaml loading in specific scenarios like StickyNotes annotation loading + /// + internal TextRange(TextPointer position1, TextPointer position2, bool useRestrictiveXamlXmlReader) : + this((ITextPointer)position1, (ITextPointer)position2) + { + _useRestrictiveXamlXmlReader = useRestrictiveXamlXmlReader; } // ignoreTextUnitBoundaries - true if normalization should ignore text @@ -1366,7 +1384,7 @@ internal string Xml try { // Parse the fragment into a separate subtree - object xamlObject = XamlReader.Load(new XmlTextReader(new System.IO.StringReader(value))); + object xamlObject = XamlReader.Load(new XmlTextReader(new System.IO.StringReader(value)), _useRestrictiveXamlXmlReader); TextElement fragment = xamlObject as TextElement; if (fragment != null) @@ -1900,6 +1918,9 @@ private enum Flags // Boolean flags, set with Flags enum. private Flags _flags; + // Boolean flag, set to true via constructor when you want to use the RestrictiveXamlXmlReader + private bool _useRestrictiveXamlXmlReader; + #endregion Private Fields } } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReader.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReader.cs index 0e76c83d435..e9be16632fb 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReader.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReader.cs @@ -50,10 +50,23 @@ public class XamlReader /// XAML text as a string /// object root generated after xaml is parsed public static object Parse(string xamlText) + { + return Parse(xamlText, useRestrictiveXamlReader: false); + } + + /// + /// Reads XAML using the passed xamlText string, building an object tree and returning the + /// root of that tree. + /// + /// XAML text as a string + /// Whether or not this method should use + /// RestrictiveXamlXmlReader to restrict instantiation of potentially dangerous types + /// object root generated after xaml is parsed + public static object Parse(string xamlText, bool useRestrictiveXamlReader) { StringReader stringReader = new StringReader(xamlText); XmlReader xmlReader = XmlReader.Create(stringReader); - return Load(xmlReader); + return Load(xmlReader, useRestrictiveXamlReader); } /// @@ -64,9 +77,23 @@ public static object Parse(string xamlText) /// parser context /// object root generated after xaml is parsed public static object Parse(string xamlText, ParserContext parserContext) + { + return Parse(xamlText, parserContext, useRestrictiveXamlReader: false); + } + + /// + /// Reads XAML using the passed xamlText, building an object tree and returning the + /// root of that tree. + /// + /// XAML text as a string + /// parser context + /// Whether or not this method should use + /// RestrictiveXamlXmlReader to restrict instantiation of potentially dangerous types + /// object root generated after xaml is parsed + public static object Parse(string xamlText, ParserContext parserContext, bool useRestrictiveXamlReader) { Stream xamlStream = new MemoryStream(UTF8Encoding.Default.GetBytes(xamlText)); - return Load(xamlStream, parserContext); + return Load(xamlStream, parserContext, useRestrictiveXamlReader); } /// @@ -77,12 +104,20 @@ public static object Parse(string xamlText, ParserContext parserContext) /// object root generated after xml parsed public static object Load(Stream stream) { - if (stream == null) - { - throw new ArgumentNullException(nameof(stream)); - } - - return Load(stream, null); + return Load(stream, null, useRestrictiveXamlReader: false); + } + + /// + /// Reads XAML from the passed stream,building an object tree and returning the + /// root of that tree. + /// + /// input as stream + /// Whether or not this method should use + /// RestrictiveXamlXmlReader to restrict instantiation of potentially dangerous types + /// object root generated after xml parsed + public static object Load(Stream stream, bool useRestrictiveXamlReader) + { + return Load(stream, null, useRestrictiveXamlReader); } /// @@ -92,15 +127,28 @@ public static object Load(Stream stream) /// Reader of xml content. /// object root generated after xml parsed public static object Load(XmlReader reader) + { + return Load(reader, useRestrictiveXamlReader: false); + } + + /// + /// Reads XAML using the passed XmlReader, building an object tree and returning the + /// root of that tree. + /// + /// Reader of xml content. + /// Whether or not this method should use + /// RestrictiveXamlXmlReader to restrict instantiation of potentially dangerous types + /// object root generated after xml parsed + public static object Load(XmlReader reader, bool useRestrictiveXamlReader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } - return Load(reader, null, XamlParseMode.Synchronous); - } - + return Load(reader, null, XamlParseMode.Synchronous, useRestrictiveXamlReader); + } + /// /// Reads XAML from the passed stream, building an object tree and returning the /// root of that tree. @@ -109,6 +157,20 @@ public static object Load(XmlReader reader) /// parser context /// object root generated after xml parsed public static object Load(Stream stream, ParserContext parserContext) + { + return Load(stream, parserContext, useRestrictiveXamlReader: false); + } + + /// + /// Reads XAML from the passed stream, building an object tree and returning the + /// root of that tree. + /// + /// input as stream + /// parser context + /// Whether or not this method should use + /// RestrictiveXamlXmlReader to restrict instantiation of potentially dangerous types + /// object root generated after xml parsed + public static object Load(Stream stream, ParserContext parserContext, bool useRestrictiveXamlReader ) { if (stream == null) { @@ -117,9 +179,12 @@ public static object Load(Stream stream, ParserContext parserContext) if (parserContext == null) { parserContext = new ParserContext(); - } - - return Load(stream, parserContext, useRestrictiveXamlReader: false); + } + + XmlReader reader = XmlReader.Create(stream, null, parserContext); + object tree = Load(reader, parserContext, XamlParseMode.Synchronous, useRestrictiveXamlReader); + stream.Close(); + return tree; } /// @@ -133,6 +198,23 @@ public static object Load(Stream stream, ParserContext parserContext) /// Notice that this is an instance method /// public object LoadAsync(Stream stream) + { + return LoadAsync(stream, useRestrictiveXamlReader: false); + } + + /// + /// Loads XAML from the given stream, building an object tree. + /// The load operation will be done asynchronously if the + /// markup specifies x:SynchronousMode="async". + /// + /// stream for the xml content + /// Whether or not this method should use + /// RestrictiveXamlXmlReader to restrict instantiation of potentially dangerous types + /// object root generated after xml parsed + /// + /// Notice that this is an instance method + /// + public object LoadAsync(Stream stream, bool useRestrictiveXamlReader) { if (stream == null) { @@ -146,27 +228,45 @@ public object LoadAsync(Stream stream) throw new InvalidOperationException(SR.Get(SRID.ParserCannotReuseXamlReader)); } - return LoadAsync(stream, null); - } - + return LoadAsync(stream, null, useRestrictiveXamlReader); + } + + /// + /// Reads XAML using the given XmlReader, building an object tree. + /// The load operation will be done asynchronously if the markup + /// specifies x:SynchronousMode="async". + /// + /// Reader for xml content. + /// object root generated after xml parsed + /// + /// Notice that this is an instance method + /// + public object LoadAsync(XmlReader reader) + { + + + return LoadAsync(reader, null, useRestrictiveXamlReader: false); + } + /// /// Reads XAML using the given XmlReader, building an object tree. /// The load operation will be done asynchronously if the markup /// specifies x:SynchronousMode="async". /// /// Reader for xml content. + /// Whether or not this method should use + /// RestrictiveXamlXmlReader to restrict instantiation of potentially dangerous types /// object root generated after xml parsed /// /// Notice that this is an instance method /// - public object LoadAsync(XmlReader reader) + public object LoadAsync(XmlReader reader, bool useRestrictiveXamlReader) { if (reader == null) { - throw new ArgumentNullException(nameof(reader)); + throw new ArgumentNullException(nameof(reader)); } - - return LoadAsync(reader, null); + return LoadAsync(reader, null, useRestrictiveXamlReader); } /// @@ -176,11 +276,30 @@ public object LoadAsync(XmlReader reader) /// /// stream for the xml content /// parser context + /// boolean flag to restrict xaml loading /// object root generated after xml parsed /// /// Notice that this is an instance method /// public object LoadAsync(Stream stream, ParserContext parserContext) + { + return LoadAsync(stream, parserContext, useRestrictiveXamlReader:false); + } + + /// + /// Loads XAML from the given stream, building an object tree. + /// The load operation will be done asynchronously if the + /// markup specifies x:SynchronousMode="async". + /// + /// stream for the xml content + /// parser context + /// Whether or not this method should use + /// RestrictiveXamlXmlReader to restrict instantiation of potentially dangerous types + /// object root generated after xml parsed + /// + /// Notice that this is an instance method + /// + public object LoadAsync(Stream stream, ParserContext parserContext , bool useRestrictiveXamlReader) { if (stream == null) { @@ -201,7 +320,7 @@ public object LoadAsync(Stream stream, ParserContext parserContext) XmlTextReader reader = new XmlTextReader(stream, XmlNodeType.Document, parserContext); reader.DtdProcessing = DtdProcessing.Prohibit; - return LoadAsync(reader, parserContext); + return LoadAsync(reader, parserContext, useRestrictiveXamlReader); } internal static bool ShouldReWrapException(Exception e, Uri baseUri) @@ -214,9 +333,14 @@ internal static bool ShouldReWrapException(Exception e, Uri baseUri) } // Not an XPE, so we need to wrap it return true; - } - - private object LoadAsync(XmlReader reader, ParserContext parserContext) + } + + private object LoadAsync(XmlReader reader, ParserContext parserContext) + { + return LoadAsync(reader, parserContext, useRestrictiveXamlReader: false); + } + + private object LoadAsync(XmlReader reader, ParserContext parserContext, bool useRestrictiveXamlReader) { if (reader == null) { @@ -252,8 +376,9 @@ private object LoadAsync(XmlReader reader, ParserContext parserContext) parserContext.XamlTypeMapper.SchemaContext : GetWpfSchemaContext(); try - { - _textReader = new System.Xaml.XamlXmlReader(reader, schemaContext, settings); + { + _textReader = (useRestrictiveXamlReader) ? new RestrictiveXamlXmlReader(reader, schemaContext, settings) : + new System.Xaml.XamlXmlReader(reader, schemaContext, settings); _stack = new XamlContextStack(() => new WpfXamlFrame()); @@ -672,44 +797,7 @@ public static XamlSchemaContext GetWpfSchemaContext() } /// - /// Reads XAML from the passed stream, building an object tree and returning the - /// root of that tree. - /// - /// input as stream - /// parser context - /// object root generated after xml parsed - internal static object Load(Stream stream, ParserContext parserContext, bool useRestrictiveXamlReader) - { - if (stream == null) - { - throw new ArgumentNullException(nameof(stream)); - } - if (parserContext == null) - { - parserContext = new ParserContext(); - } - - XmlReader reader = XmlReader.Create(stream, null, parserContext); - object tree = Load(reader, parserContext, XamlParseMode.Synchronous, useRestrictiveXamlReader); - stream.Close(); - return tree; - } - - /// - /// Reads XAML using the passed XmlReader, building an object tree and returning the - /// root of that tree. - /// - /// Reader of xml content. - /// object root generated after xml parsed - internal static object Load(XmlReader reader, bool useRestrictiveXamlReader = false) - { - if (reader == null) - { - throw new ArgumentNullException(nameof(reader)); - } - return Load(reader, null, XamlParseMode.Synchronous, useRestrictiveXamlReader); - } /// /// Reads XAML from the passed stream, building an object tree and returning the @@ -753,7 +841,7 @@ internal static object Load( parseMode == XamlParseMode.Asynchronous) { XamlReader xamlReader = new XamlReader(); - return xamlReader.LoadAsync(reader, parserContext); + return xamlReader.LoadAsync(reader, parserContext, useRestrictiveXamlReader); } if (parserContext == null) diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs index 58e1f93bf0a..67b64c75991 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/ref/PresentationFramework.cs @@ -11391,14 +11391,22 @@ public event System.ComponentModel.AsyncCompletedEventHandler LoadCompleted { ad public void CancelAsync() { } public static System.Xaml.XamlSchemaContext GetWpfSchemaContext() { throw null; } public static object Load(System.IO.Stream stream) { throw null; } + public static object Load(System.IO.Stream stream, bool useRestrictiveXamlReader) { throw null; } public static object Load(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext) { throw null; } + public static object Load(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext, bool useRestrictiveXamlReader) { throw null; } public static object Load(System.Xaml.XamlReader reader) { throw null; } public static object Load(System.Xml.XmlReader reader) { throw null; } + public static object Load(System.Xml.XmlReader reader, bool useRestrictiveXamlReader) { throw null; } public object LoadAsync(System.IO.Stream stream) { throw null; } + public object LoadAsync(System.IO.Stream stream, bool useRestrictiveXamlReader) { throw null; } public object LoadAsync(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext) { throw null; } + public object LoadAsync(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext, bool useRestrictiveXamlReader) { throw null; } public object LoadAsync(System.Xml.XmlReader reader) { throw null; } + public object LoadAsync(System.Xml.XmlReader reader, bool useRestrictiveXamlReader) { throw null; } public static object Parse(string xamlText) { throw null; } + public static object Parse(string xamlText, bool useRestrictiveXamlReader) { throw null; } public static object Parse(string xamlText, System.Windows.Markup.ParserContext parserContext) { throw null; } + public static object Parse(string xamlText, System.Windows.Markup.ParserContext parserContext, bool useRestrictiveXamlReader) { throw null; } } public partial class XamlTypeMapper { diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsDocument.cs b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsDocument.cs index 12fe4b37535..81c72079988 100644 --- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsDocument.cs +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsDocument.cs @@ -629,7 +629,7 @@ XpsImageType imageType parserContext.BaseUri = PackUriHelper.Create(Uri, CurrentXpsManager.StartingPart.Uri); - object fixedObject = XamlReader.Load(CurrentXpsManager.StartingPart.GetStream(), parserContext); + object fixedObject = XamlReader.Load(CurrentXpsManager.StartingPart.GetStream(), parserContext, useRestrictiveXamlReader: true); if (!(fixedObject is FixedDocumentSequence) ) { throw new XpsPackagingException(SR.Get(SRID.ReachPackaging_NotAFixedDocumentSequence));