diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs index affd635ff1e77..00666a5d34482 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml { /// diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs index 528cad5a3f02b..2b8f5d247b6e1 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Xml.Schema; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IncrementalReadDecoders.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IncrementalReadDecoders.cs index 912736c508147..4cf58e2b3a930 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IncrementalReadDecoders.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IncrementalReadDecoders.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Xml @@ -38,7 +39,7 @@ internal class IncrementalReadDummyDecoder : IncrementalReadDecoder // internal class IncrementalReadCharsDecoder : IncrementalReadDecoder { - private char[] _buffer; + private char[]? _buffer; private int _startIndex; private int _curIndex; private int _endIndex; @@ -61,6 +62,7 @@ internal override bool IsFull internal override int Decode(char[] chars, int startPos, int len) { + Debug.Assert(_buffer != null); Debug.Assert(chars != null); Debug.Assert(len >= 0); Debug.Assert(startPos >= 0); @@ -73,6 +75,7 @@ internal override int Decode(char[] chars, int startPos, int len) { copyCount = len; } + Buffer.BlockCopy(chars, startPos * 2, _buffer, _curIndex * 2, copyCount * 2); _curIndex += copyCount; @@ -81,6 +84,7 @@ internal override int Decode(char[] chars, int startPos, int len) internal override int Decode(string str, int startPos, int len) { + Debug.Assert(_buffer != null); Debug.Assert(str != null); Debug.Assert(len >= 0); Debug.Assert(startPos >= 0); @@ -93,6 +97,7 @@ internal override int Decode(string str, int startPos, int len) { copyCount = len; } + str.CopyTo(startPos, _buffer, _curIndex, copyCount); _curIndex += copyCount; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs index a36958ec93901..f17a495025efb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; namespace System diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/NamespaceHandling.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/NamespaceHandling.cs index 9fdb5af95a18b..9627334206f0a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/NamespaceHandling.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/NamespaceHandling.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml { // diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs index ea8030fe3f539..cf7b19cd88a44 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml { using System; @@ -24,9 +25,9 @@ internal class QueryOutputWriter : XmlRawWriter { private readonly XmlRawWriter _wrapped; private bool _inCDataSection; - private readonly Dictionary _lookupCDataElems; - private readonly BitStack _bitsCData; - private readonly XmlQualifiedName _qnameCData; + private readonly Dictionary? _lookupCDataElems; + private readonly BitStack? _bitsCData; + private readonly XmlQualifiedName? _qnameCData; private bool _outputDocType; private readonly bool _checkWellFormedDoc; private bool _hasDocElem; @@ -86,7 +87,7 @@ public QueryOutputWriter(XmlRawWriter writer, XmlWriterSettings settings) /// /// Get and set the namespace resolver that's used by this RawWriter to resolve prefixes. /// - internal override IXmlNamespaceResolver NamespaceResolver + internal override IXmlNamespaceResolver? NamespaceResolver { get { @@ -119,7 +120,7 @@ public override XmlWriterSettings Settings { get { - XmlWriterSettings settings = _wrapped.Settings; + XmlWriterSettings settings = _wrapped.Settings!; settings.ReadOnly = false; settings.DocTypeSystem = _systemId; @@ -133,7 +134,7 @@ public override XmlWriterSettings Settings /// /// Suppress this explicit call to WriteDocType if information was provided by XmlWriterSettings. /// - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { if (_publicId == null && _systemId == null) { @@ -146,7 +147,7 @@ public override void WriteDocType(string name, string pubid, string sysid, strin /// Check well-formedness, possibly output doc-type-decl, and determine whether this element is a /// CData section element. /// - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { EndCDataSection(); @@ -164,7 +165,7 @@ public override void WriteStartElement(string prefix, string localName, string n if (_outputDocType) { _wrapped.WriteDocType( - prefix.Length != 0 ? prefix + ":" + localName : localName, + string.IsNullOrEmpty(prefix) ? localName : prefix + ":" + localName, _publicId, _systemId, null); @@ -177,8 +178,8 @@ public override void WriteStartElement(string prefix, string localName, string n if (_lookupCDataElems != null) { // Determine whether this element is a CData section element - _qnameCData.Init(localName, ns); - _bitsCData.PushBit(_lookupCDataElems.ContainsKey(_qnameCData)); + _qnameCData!.Init(localName, ns); + _bitsCData!.PushBit(_lookupCDataElems.ContainsKey(_qnameCData)); } } @@ -192,7 +193,7 @@ internal override void WriteEndElement(string prefix, string localName, string n _depth--; if (_lookupCDataElems != null) - _bitsCData.PopBit(); + _bitsCData!.PopBit(); } internal override void WriteFullEndElement(string prefix, string localName, string ns) @@ -205,7 +206,7 @@ internal override void WriteFullEndElement(string prefix, string localName, stri _depth--; if (_lookupCDataElems != null) - _bitsCData.PopBit(); + _bitsCData!.PopBit(); } internal override void StartElementContent() @@ -213,7 +214,7 @@ internal override void StartElementContent() _wrapped.StartElementContent(); } - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { _inAttr = true; _wrapped.WriteStartAttribute(prefix, localName, ns); @@ -248,7 +249,7 @@ internal override void WriteEndNamespaceDeclaration() _wrapped.WriteEndNamespaceDeclaration(); } - public override void WriteCData(string text) + public override void WriteCData(string? text) { _wrapped.WriteCData(text); } @@ -273,7 +274,7 @@ public override void WriteWhitespace(string ws) _wrapped.WriteWhitespace(ws); } - public override void WriteString(string text) + public override void WriteString(string? text) { if (!_inAttr && (_inCDataSection || StartCDataSection())) _wrapped.WriteCData(text); @@ -351,7 +352,7 @@ public override void Flush() private bool StartCDataSection() { Debug.Assert(!_inCDataSection); - if (_lookupCDataElems != null && _bitsCData.PeekBit()) + if (_lookupCDataElems != null && _bitsCData!.PeekBit()) { _inCDataSection = true; return true; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs index 462854bc4c554..4f6ea549c7459 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Diagnostics; @@ -25,9 +26,9 @@ internal class QueryOutputWriterV1 : XmlWriter { private readonly XmlWriter _wrapped; private bool _inCDataSection; - private readonly Dictionary _lookupCDataElems; - private readonly BitStack _bitsCData; - private readonly XmlQualifiedName _qnameCData; + private readonly Dictionary? _lookupCDataElems; + private readonly BitStack? _bitsCData; + private readonly XmlQualifiedName? _qnameCData; private bool _outputDocType, _inAttr; private readonly string _systemId, _publicId; @@ -71,7 +72,7 @@ public QueryOutputWriterV1(XmlWriter writer, XmlWriterSettings settings) if (settings.CDataSectionElements != null && settings.CDataSectionElements.Count > 0) { _bitsCData = new BitStack(); - _lookupCDataElems = new Dictionary(); + _lookupCDataElems = new Dictionary(); _qnameCData = new XmlQualifiedName(); // Add each element name to the lookup table @@ -122,7 +123,7 @@ public override void WriteEndDocument() /// /// Suppress this explicit call to WriteDocType if information was provided by XmlWriterSettings. /// - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { if (_publicId == null && _systemId == null) { @@ -135,7 +136,7 @@ public override void WriteDocType(string name, string pubid, string sysid, strin /// Output doc-type-decl on the first element, and determine whether this element is a /// CData section element. /// - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { EndCDataSection(); @@ -146,11 +147,12 @@ public override void WriteStartElement(string prefix, string localName, string n if (ws == WriteState.Start || ws == WriteState.Prolog) { _wrapped.WriteDocType( - prefix.Length != 0 ? prefix + ":" + localName : localName, + string.IsNullOrEmpty(prefix) ? localName : prefix + ":" + localName, _publicId, _systemId, null); } + _outputDocType = false; } @@ -158,6 +160,9 @@ public override void WriteStartElement(string prefix, string localName, string n if (_lookupCDataElems != null) { + Debug.Assert(_qnameCData != null); + Debug.Assert(_bitsCData != null); + // Determine whether this element is a CData section element _qnameCData.Init(localName, ns); _bitsCData.PushBit(_lookupCDataElems.ContainsKey(_qnameCData)); @@ -171,7 +176,10 @@ public override void WriteEndElement() _wrapped.WriteEndElement(); if (_lookupCDataElems != null) + { + Debug.Assert(_bitsCData != null); _bitsCData.PopBit(); + } } public override void WriteFullEndElement() @@ -181,10 +189,13 @@ public override void WriteFullEndElement() _wrapped.WriteFullEndElement(); if (_lookupCDataElems != null) + { + Debug.Assert(_bitsCData != null); _bitsCData.PopBit(); + } } - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { _inAttr = true; _wrapped.WriteStartAttribute(prefix, localName, ns); @@ -196,7 +207,7 @@ public override void WriteEndAttribute() _wrapped.WriteEndAttribute(); } - public override void WriteCData(string text) + public override void WriteCData(string? text) { _wrapped.WriteCData(text); } @@ -221,7 +232,7 @@ public override void WriteWhitespace(string ws) _wrapped.WriteWhitespace(ws); } - public override void WriteString(string text) + public override void WriteString(string? text) { if (!_inAttr && (_inCDataSection || StartCDataSection())) _wrapped.WriteCData(text); @@ -291,7 +302,7 @@ public override void Flush() _wrapped.Flush(); } - public override string LookupPrefix(string ns) + public override string? LookupPrefix(string ns) { return _wrapped.LookupPrefix(ns); } @@ -308,11 +319,12 @@ public override string LookupPrefix(string ns) private bool StartCDataSection() { Debug.Assert(!_inCDataSection); - if (_lookupCDataElems != null && _bitsCData.PeekBit()) + if (_lookupCDataElems != null && _bitsCData!.PeekBit()) { _inCDataSection = true; return true; } + return false; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs index 952c3d2348e99..81f8a09aad9bc 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Diagnostics; @@ -43,10 +44,10 @@ internal abstract partial class XmlRawWriter : XmlWriter // Fields // // base64 converter - protected XmlRawWriterBase64Encoder base64Encoder; + protected XmlRawWriterBase64Encoder? base64Encoder; // namespace resolver - protected IXmlNamespaceResolver resolver; + protected IXmlNamespaceResolver? resolver; // // XmlWriter implementation @@ -68,7 +69,7 @@ public override void WriteEndDocument() throw new InvalidOperationException(SR.Xml_InvalidOperation); } - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { } @@ -91,6 +92,7 @@ public override void WriteBase64(byte[] buffer, int index, int count) { base64Encoder = new XmlRawWriterBase64Encoder(this); } + // Encode will call WriteRaw to write out the encoded characters base64Encoder.Encode(buffer, index, count); } @@ -135,13 +137,13 @@ public override void WriteName(string name) } // Raw writers do not have to verify QName values. - public override void WriteQualifiedName(string localName, string ns) + public override void WriteQualifiedName(string localName, string? ns) { throw new InvalidOperationException(SR.Xml_InvalidOperation); } // Forward call to WriteString(string). - public override void WriteCData(string text) + public override void WriteCData(string? text) { WriteString(text); } @@ -184,17 +186,18 @@ public override void WriteRaw(string data) } // Override in order to handle Xml simple typed values and to pass resolver for QName values - public override void WriteValue(object value) + public override void WriteValue(object? value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } + WriteString(XmlUntypedConverter.Untyped.ToString(value, resolver)); } // Override in order to handle Xml simple typed values and to pass resolver for QName values - public override void WriteValue(string value) + public override void WriteValue(string? value) { WriteString(value); } @@ -227,7 +230,7 @@ public override void WriteNode(System.Xml.XPath.XPathNavigator navigator, bool d // // Get and set the namespace resolver that's used by this RawWriter to resolve prefixes. - internal virtual IXmlNamespaceResolver NamespaceResolver + internal virtual IXmlNamespaceResolver? NamespaceResolver { get { @@ -275,6 +278,7 @@ internal virtual void WriteQualifiedName(string prefix, string localName, string WriteString(prefix); WriteString(":"); } + WriteString(localName); } @@ -311,6 +315,7 @@ internal virtual void WriteEndNamespaceDeclaration() internal virtual void WriteEndBase64() { // The Flush will call WriteRaw to write out the rest of the encoded characters + Debug.Assert(base64Encoder != null); base64Encoder.Flush(); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs index b602201b1eb20..61a23299b99da 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Diagnostics; @@ -60,7 +61,7 @@ public override Task WriteEndDocumentAsync() throw new InvalidOperationException(SR.Xml_InvalidOperation); } - public override Task WriteDocTypeAsync(string name, string pubid, string sysid, string subset) + public override Task WriteDocTypeAsync(string name, string? pubid, string? sysid, string subset) { return Task.CompletedTask; } @@ -101,7 +102,7 @@ public override Task WriteNameAsync(string name) } // Raw writers do not have to verify QName values. - public override Task WriteQualifiedNameAsync(string localName, string ns) + public override Task WriteQualifiedNameAsync(string localName, string? ns) { throw new InvalidOperationException(SR.Xml_InvalidOperation); } @@ -200,6 +201,7 @@ internal virtual async Task WriteQualifiedNameAsync(string prefix, string localN await WriteStringAsync(prefix).ConfigureAwait(false); await WriteStringAsync(":").ConfigureAwait(false); } + await WriteStringAsync(localName).ConfigureAwait(false); } @@ -224,6 +226,7 @@ internal virtual Task WriteEndNamespaceDeclarationAsync() internal virtual Task WriteEndBase64Async() { // The Flush will call WriteRaw to write out the rest of the encoded characters + Debug.Assert(base64Encoder != null); return base64Encoder.FlushAsync(); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs index 93eb9bb60d85e..67d70187bd0a8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs @@ -651,6 +651,7 @@ private XmlReader AddValidationInternal(XmlReader reader, XmlResolver? resolver, { reader = new XsdValidatingReader(reader, GetXmlResolver_CheckConfig(), this); } + return reader; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index 912615c9a1662..2e69660d785a3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Text; @@ -29,7 +30,7 @@ internal class XmlTextEncoder private char _quoteChar; // caching of attribute value - private StringBuilder _attrValue; + private StringBuilder? _attrValue; private bool _cacheAttrValue; // XmlCharType @@ -77,8 +78,10 @@ internal void EndAttribute() { if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Length = 0; } + _inAttribute = false; _cacheAttrValue = false; } @@ -89,6 +92,7 @@ internal string AttributeValue { if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); return _attrValue.ToString(); } else @@ -134,6 +138,7 @@ internal void Write(char[] array, int offset, int count) if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append(array, offset, count); } @@ -241,6 +246,7 @@ internal void WriteSurrogateCharEntity(char lowChar, char highChar) if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append(highChar); _attrValue.Append(lowChar); } @@ -259,6 +265,7 @@ internal void Write(string text) if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append(text); } @@ -395,8 +402,10 @@ internal void WriteRawWithSurrogateChecking(string text) { return; } + if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append(text); } @@ -469,8 +478,10 @@ internal void WriteRaw(char[] array, int offset, int count) if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append(array, offset, count); } + _textWriter.Write(array, offset, count); } @@ -486,10 +497,12 @@ internal void WriteCharEntity(char ch) string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo); if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append("&#x"); _attrValue.Append(strVal); _attrValue.Append(';'); } + WriteCharEntityImpl(strVal); } @@ -497,10 +510,12 @@ internal void WriteEntityRef(string name) { if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append('&'); _attrValue.Append(name); _attrValue.Append(';'); } + WriteEntityRefImpl(name); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.Unix.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.Unix.cs index 96e32fd9d3a1d..bc856150e1304 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.Unix.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.Unix.cs @@ -2,11 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml { internal partial class XmlTextReaderImpl { - static partial void ConvertAbsoluteUnixPathToAbsoluteUri(ref string url, XmlResolver resolver) + static partial void ConvertAbsoluteUnixPathToAbsoluteUri(ref string url, XmlResolver? resolver) { // new Uri(uri, UriKind.RelativeOrAbsolute) returns a Relative Uri for absolute unix paths (e.g. /tmp). // We convert the native unix path to a 'file://' uri string to make it an Absolute Uri. @@ -27,4 +28,4 @@ internal partial class XmlTextReaderImpl } } } -} \ No newline at end of file +} diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs index ae7235e0f64d4..7b181e4b798bb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs @@ -8410,6 +8410,7 @@ private int IncrementalRead(Array array, int index, int count) private int IncrementalRead() { Debug.Assert(_incReadDecoder != null); + Debug.Assert(_ps.chars != null); int charsDecoded = 0; OuterContinue: @@ -8505,7 +8506,6 @@ private int IncrementalRead() _incReadState == IncrementalReadState.Attributes || _incReadState == IncrementalReadState.AttributeValue); - Debug.Assert(_ps.chars != null); char[] chars = _ps.chars; startPos = _ps.charPos; pos = startPos; @@ -9633,6 +9633,7 @@ private int ReadContentAsBinary(byte[] buffer, int index, int count) if (_incReadState == IncrementalReadState.ReadContentAsBinary_OnPartialValue) { _curNode.SetValue(string.Empty); + Debug.Assert(_ps.chars != null); // read next chunk of text bool endOfValue = false; @@ -9657,12 +9658,12 @@ private int ReadContentAsBinary(byte[] buffer, int index, int count) } startPos += charsRead; } + _incReadState = endOfValue ? IncrementalReadState.ReadContentAsBinary_OnCachedValue : IncrementalReadState.ReadContentAsBinary_OnPartialValue; _readValueOffset = 0; if (_incReadDecoder.IsFull) { - Debug.Assert(_ps.chars != null); _curNode.SetValue(_ps.chars, startPos, endPos - startPos); // adjust line info for the chunk that has been already decoded AdjustLineInfo(_ps.chars, startPos - charsRead, startPos, _ps.eolNormalized, ref _incReadLineInfo); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs index dc9a77df0696b..7f65f254fa31c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -25,7 +26,7 @@ public enum Formatting // and not Mixed Content (http://www.w3.org/TR/1998/REC-xml-19980210#sec-mixed-content) // according to the XML 1.0 definitions of these terms. Indented, - }; + } // Represents a writer that provides fast non-cached forward-only way of generating XML streams // containing XML documents that conform to the W3CExtensible Markup Language (XML) 1.0 specification @@ -47,12 +48,12 @@ private enum NamespaceState private struct TagInfo { - internal string name; - internal string prefix; + internal string? name; + internal string? prefix; internal string defaultNs; internal NamespaceState defaultNsState; internal XmlSpace xmlSpace; - internal string xmlLang; + internal string? xmlLang; internal int prevNsTop; internal int prefixCount; internal bool mixed; // whether to pretty print the contents of this element. @@ -131,9 +132,9 @@ private enum Token // Fields // // output - private readonly TextWriter _textWriter; - private readonly XmlTextEncoder _xmlEncoder; - private readonly Encoding _encoding; + private readonly TextWriter _textWriter = null!; + private readonly XmlTextEncoder _xmlEncoder = null!; + private readonly Encoding? _encoding; // formatting private Formatting _formatting; @@ -159,20 +160,20 @@ private static char[] CreateDefaultIndentChars() private Token _lastToken; // Base64 content - private XmlTextWriterBase64Encoder _base64Encoder; + private XmlTextWriterBase64Encoder? _base64Encoder; // misc private char _quoteChar; private char _curQuoteChar; private bool _namespaces; private SpecialAttr _specialAttr; - private string _prefixForXmlNs; + private string? _prefixForXmlNs; private bool _flush; // namespaces private Namespace[] _nsStack; private int _nsTop; - private Dictionary _nsHashtable; + private Dictionary? _nsHashtable; private bool _useNsHashtable; // char types @@ -259,7 +260,7 @@ private static char[] CreateDefaultIndentChars() // // Constructors // - internal XmlTextWriter() + private XmlTextWriter() { _namespaces = true; _formatting = Formatting.None; @@ -281,7 +282,7 @@ internal XmlTextWriter() } // Creates an instance of the XmlTextWriter class using the specified stream. - public XmlTextWriter(Stream w, Encoding encoding) : this() + public XmlTextWriter(Stream w, Encoding? encoding) : this() { _encoding = encoding; if (encoding != null) @@ -313,12 +314,18 @@ public XmlTextWriter(TextWriter w) : this() // XmlTextWriter properties // // Gets the XmlTextWriter base stream. - public Stream BaseStream + public Stream? BaseStream { get { - StreamWriter streamWriter = _textWriter as StreamWriter; - return (streamWriter == null ? null : streamWriter.BaseStream); + if (_textWriter is StreamWriter streamWriter) + { + return streamWriter.BaseStream; + } + else + { + return null; + } } } @@ -437,7 +444,7 @@ public override void WriteEndDocument() } // Writes out the DOCTYPE declaration with the specified name and optional attributes. - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { try { @@ -476,7 +483,7 @@ public override void WriteDocType(string name, string pubid, string sysid, strin } // Writes out the specified start tag and associates it with the given namespace and prefix. - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { try { @@ -503,7 +510,7 @@ public override void WriteStartElement(string prefix, string localName, string n { if (prefix == null) { - string definedPrefix = FindPrefix(ns); + string? definedPrefix = FindPrefix(ns); if (definedPrefix != null) { prefix = definedPrefix; @@ -523,6 +530,7 @@ public override void WriteStartElement(string prefix, string localName, string n { prefix = null; } + VerifyPrefixXml(prefix, ns); PushNamespace(prefix, ns, false); // define } @@ -565,7 +573,7 @@ public override void WriteFullEndElement() } // Writes the start of an attribute. - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { try { @@ -607,6 +615,7 @@ public override void WriteStartAttribute(string prefix, string localName, string { throw new ArgumentException(SR.Xml_XmlnsBelongsToReservedNs); } + if (localName == null || localName.Length == 0) { localName = prefix; @@ -617,6 +626,7 @@ public override void WriteStartAttribute(string prefix, string localName, string { _prefixForXmlNs = localName; } + _specialAttr = SpecialAttr.XmlNs; } else if (prefix == null && localName == "xmlns") @@ -626,6 +636,7 @@ public override void WriteStartAttribute(string prefix, string localName, string // add the below line back in when DOM is fixed throw new ArgumentException(SR.Xml_XmlnsBelongsToReservedNs); } + _specialAttr = SpecialAttr.XmlNs; _prefixForXmlNs = null; } @@ -651,8 +662,9 @@ public override void WriteStartAttribute(string prefix, string localName, string { prefix = null; } + // Now verify prefix validity - string definedPrefix = FindPrefix(ns); + string? definedPrefix = FindPrefix(ns); if (definedPrefix != null && (prefix == null || prefix == definedPrefix)) { prefix = definedPrefix; @@ -667,6 +679,7 @@ public override void WriteStartAttribute(string prefix, string localName, string } } } + if (prefix != null && prefix.Length != 0) { _textWriter.Write(prefix); @@ -679,15 +692,18 @@ public override void WriteStartAttribute(string prefix, string localName, string { throw new ArgumentException(SR.Xml_NoNamespaces); } + if (localName == "xml:lang") { _specialAttr = SpecialAttr.XmlLang; } + else if (localName == "xml:space") { _specialAttr = SpecialAttr.XmlSpace; } } + _xmlEncoder.StartAttribute(_specialAttr != SpecialAttr.None); _textWriter.Write(localName); @@ -721,7 +737,7 @@ public override void WriteEndAttribute() } // Writes out a <![CDATA[...]]> block containing the specified text. - public override void WriteCData(string text) + public override void WriteCData(string? text) { try { @@ -730,12 +746,14 @@ public override void WriteCData(string text) { throw new ArgumentException(SR.Xml_InvalidCDataChars); } + _textWriter.Write(""); } catch @@ -770,7 +788,7 @@ public override void WriteComment(string text) } // Writes out a processing instruction with a space between the name and text as follows: - public override void WriteProcessingInstruction(string name, string text) + public override void WriteProcessingInstruction(string name, string? text) { try { @@ -778,10 +796,12 @@ public override void WriteProcessingInstruction(string name, string text) { throw new ArgumentException(SR.Xml_InvalidPiChars); } + if (0 == string.Compare(name, "xml", StringComparison.OrdinalIgnoreCase) && _stateTable == s_stateTableDocument) { throw new ArgumentException(SR.Xml_DupXmlDecl); } + AutoComplete(Token.PI); InternalWriteProcessingInstruction(name, text); } @@ -848,7 +868,7 @@ public override void WriteWhitespace(string ws) } // Writes out the specified text content. - public override void WriteString(string text) + public override void WriteString(string? text) { try { @@ -1040,7 +1060,7 @@ public override void WriteName(string name) } // Writes out the specified namespace-qualified name by looking up the prefix that is in scope for the given namespace. - public override void WriteQualifiedName(string localName, string ns) + public override void WriteQualifiedName(string localName, string? ns) { try { @@ -1049,16 +1069,18 @@ public override void WriteQualifiedName(string localName, string ns) { if (ns != null && ns.Length != 0 && ns != _stack[_top].defaultNs) { - string prefix = FindPrefix(ns); + string? prefix = FindPrefix(ns); if (prefix == null) { if (_currentState != State.Attribute) { throw new ArgumentException(SR.Format(SR.Xml_UndefNamespace, ns)); } - prefix = GeneratePrefix(); // need a prefix if + + prefix = GeneratePrefix(); PushNamespace(prefix, ns, false); } + if (prefix.Length != 0) { InternalWriteName(prefix, true); @@ -1070,6 +1092,7 @@ public override void WriteQualifiedName(string localName, string ns) { throw new ArgumentException(SR.Xml_NoNamespaces); } + InternalWriteName(localName, true); } catch @@ -1080,17 +1103,19 @@ public override void WriteQualifiedName(string localName, string ns) } // Returns the closest prefix defined in the current namespace scope for the specified namespace URI. - public override string LookupPrefix(string ns) + public override string? LookupPrefix(string ns) { if (ns == null || ns.Length == 0) { throw new ArgumentException(SR.Xml_EmptyName); } - string s = FindPrefix(ns); + + string? s = FindPrefix(ns); if (s == null && ns == _stack[_top].defaultNs) { s = string.Empty; } + return s; } @@ -1110,16 +1135,18 @@ public override XmlSpace XmlSpace } // Gets the current xml:lang scope. - public override string XmlLang + public override string? XmlLang { get { for (int i = _top; i > 0; i--) { - string xlang = _stack[i].xmlLang; + string? xlang = _stack[i].xmlLang; + if (xlang != null) return xlang; } + return null; } } @@ -1444,7 +1471,7 @@ private void Indent(bool beforeEndElement) // pushes new namespace scope, and returns generated prefix, if one // was needed to resolve conflicts. - private void PushNamespace(string prefix, string ns, bool declared) + private void PushNamespace(string? prefix, string ns, bool declared) { if (XmlReservedNs.NsXmlNs == ns) { @@ -1469,6 +1496,7 @@ private void PushNamespace(string prefix, string ns, bool declared) Debug.Fail("Should have never come here"); return; } + _stack[_top].defaultNsState = (declared ? NamespaceState.DeclaredAndWrittenOut : NamespaceState.DeclaredButNotWrittenOut); } else @@ -1497,6 +1525,7 @@ private void PushNamespace(string prefix, string ns, bool declared) _nsStack[existingNsIndex].declared = true; // old one is silenced now } } + AddNamespace(prefix, ns, declared); } } @@ -1521,28 +1550,36 @@ private void AddNamespace(string prefix, string ns, bool declared) { // add all _nsHashtable = new Dictionary(); + _useNsHashtable = true; + for (int i = 0; i <= nsIndex; i++) { AddToNamespaceHashtable(i); } - _useNsHashtable = true; } } private void AddToNamespaceHashtable(int namespaceIndex) { + Debug.Assert(_useNsHashtable); + Debug.Assert(_nsHashtable != null); + string prefix = _nsStack[namespaceIndex].prefix; int existingNsIndex; + if (_nsHashtable.TryGetValue(prefix, out existingNsIndex)) { _nsStack[namespaceIndex].prevNsIndex = existingNsIndex; } + _nsHashtable[prefix] = namespaceIndex; } private void PopNamespaces(int indexFrom, int indexTo) { Debug.Assert(_useNsHashtable); + Debug.Assert(_nsHashtable != null); + for (int i = indexTo; i >= indexFrom; i--) { Debug.Assert(_nsHashtable.ContainsKey(_nsStack[i].prefix)); @@ -1564,16 +1601,18 @@ private string GeneratePrefix() + "p" + temp.ToString("d", CultureInfo.InvariantCulture); } - private void InternalWriteProcessingInstruction(string name, string text) + private void InternalWriteProcessingInstruction(string name, string? text) { _textWriter.Write(""); } @@ -1581,6 +1620,7 @@ private int LookupNamespace(string prefix) { if (_useNsHashtable) { + Debug.Assert(_nsHashtable != null); int nsIndex; if (_nsHashtable.TryGetValue(prefix, out nsIndex)) { @@ -1597,6 +1637,7 @@ private int LookupNamespace(string prefix) } } } + return -1; } @@ -1604,7 +1645,9 @@ private int LookupNamespaceInCurrentScope(string prefix) { if (_useNsHashtable) { + Debug.Assert(_nsHashtable != null); int nsIndex; + if (_nsHashtable.TryGetValue(prefix, out nsIndex)) { if (nsIndex > _stack[_top].prevNsTop) @@ -1626,7 +1669,7 @@ private int LookupNamespaceInCurrentScope(string prefix) return -1; } - private string FindPrefix(string ns) + private string? FindPrefix(string ns) { for (int i = _nsTop; i >= 0; i--) { @@ -1638,6 +1681,7 @@ private string FindPrefix(string ns) } } } + return null; } @@ -1745,7 +1789,7 @@ private void HandleSpecialAttribute() } - private void VerifyPrefixXml(string prefix, string ns) + private void VerifyPrefixXml(string? prefix, string ns) { if (prefix != null && prefix.Length == 3) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs index d412522dd279c..07960b08492d8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs @@ -74,7 +74,7 @@ public abstract partial class XmlWriter : IDisposable // Writes out the DOCTYPE declaration with the specified name and optional attributes. - public abstract void WriteDocType(string name, string? pubid, string? sysid, string subset); + public abstract void WriteDocType(string name, string? pubid, string? sysid, string? subset); // Writes out the specified start tag and associates it with the given namespace. public void WriteStartElement(string localName, string? ns) @@ -146,7 +146,7 @@ public void WriteStartAttribute(string localName) // Writes out a ; block containing the specified text. - public abstract void WriteCData(string text); + public abstract void WriteCData(string? text); // Writes out a comment ; containing the specified text. @@ -170,7 +170,7 @@ public void WriteStartAttribute(string localName) // Writes out the specified text content. - public abstract void WriteString(string text); + public abstract void WriteString(string? text); // Write out the given surrogate pair as an entity reference. @@ -221,7 +221,7 @@ public virtual XmlSpace XmlSpace } // Gets the current xml:lang scope. - public virtual string XmlLang + public virtual string? XmlLang { get { @@ -282,6 +282,7 @@ public virtual void WriteValue(string? value) { return; } + WriteString(value); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs index 7a6b5928b545f..2115a780f0dd9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.IO; using System.Text; using System.Xml.Schema; @@ -11,6 +12,7 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.Versioning; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -18,9 +20,9 @@ namespace System.Xml internal class AttributePSVIInfo { - internal string localName; - internal string namespaceUri; - internal object typedAttributeValue; + internal string? localName; + internal string? namespaceUri; + internal object? typedAttributeValue; internal XmlSchemaInfo attributeSchemaInfo; internal AttributePSVIInfo() @@ -55,51 +57,52 @@ private enum ValidatingReaderState EOF = 9, Error = 10, } - //Validation + + // Validation private XmlReader _coreReader; - private readonly IXmlNamespaceResolver _coreReaderNSResolver; + private readonly IXmlNamespaceResolver? _coreReaderNSResolver; private readonly IXmlNamespaceResolver _thisNSResolver; - private XmlSchemaValidator _validator; - private readonly XmlResolver _xmlResolver; - private readonly ValidationEventHandler _validationEvent; + private XmlSchemaValidator _validator = null!; + private readonly XmlResolver? _xmlResolver; + private readonly ValidationEventHandler? _validationEvent; private ValidatingReaderState _validationState; private XmlValueGetter _valueGetter; // namespace management - private readonly XmlNamespaceManager _nsManager; + private readonly XmlNamespaceManager? _nsManager; private readonly bool _manageNamespaces; private readonly bool _processInlineSchema; private bool _replayCache; - //Current Node handling - private ValidatingReaderNodeData _cachedNode; //Used to cache current node when looking ahead or default attributes - private AttributePSVIInfo _attributePSVI; + // Current Node handling + private ValidatingReaderNodeData? _cachedNode; // Used to cache current node when looking ahead or default attributes + private AttributePSVIInfo? _attributePSVI; - //Attributes - private int _attributeCount; //Total count of attributes including default + // Attributes + private int _attributeCount; // Total count of attributes including default private int _coreReaderAttributeCount; private int _currentAttrIndex; private AttributePSVIInfo[] _attributePSVINodes; private ArrayList _defaultAttributes; - //Inline Schema - private Parser _inlineSchemaParser = null; + // Inline Schema + private Parser? _inlineSchemaParser = null; - //Typed Value & PSVI - private object _atomicValue; + // Typed Value & PSVI + private object? _atomicValue; private XmlSchemaInfo _xmlSchemaInfo; // original string of the atomic value - private string _originalAtomicValueString; + private string? _originalAtomicValueString; - //cached coreReader information + // cached coreReader information private readonly XmlNameTable _coreReaderNameTable; - private XsdCachingReader _cachingReader; + private XsdCachingReader? _cachingReader; - //ReadAttributeValue TextNode - private ValidatingReaderNodeData _textNode; + // ReadAttributeValue TextNode + private ValidatingReaderNodeData? _textNode; - //To avoid SchemaNames creation + // To avoid SchemaNames creation private string _nsXmlNs; private string _nsXs; private string _nsXsi; @@ -109,20 +112,20 @@ private enum ValidatingReaderState private string _xsiSchemaLocation; private string _xsiNoNamespaceSchemaLocation; - //Underlying reader's IXmlLineInfo - private IXmlLineInfo _lineInfo; + // Underlying reader's IXmlLineInfo + private IXmlLineInfo? _lineInfo; // helpers for Read[Element]ContentAs{Base64,BinHex} methods - private ReadContentAsBinaryHelper _readBinaryHelper; + private ReadContentAsBinaryHelper? _readBinaryHelper; private ValidatingReaderState _savedState; - //Constants + // Constants private const int InitialAttributeCount = 8; - private static volatile Type s_typeOfString; + private static volatile Type s_typeOfString = null!; - //Constructor - internal XsdValidatingReader(XmlReader reader, XmlResolver xmlResolver, XmlReaderSettings readerSettings, XmlSchemaObject partialValidationType) + // Constructor + internal XsdValidatingReader(XmlReader reader, XmlResolver? xmlResolver, XmlReaderSettings readerSettings, XmlSchemaObject? partialValidationType) { _coreReader = reader; _coreReaderNSResolver = reader as IXmlNamespaceResolver; @@ -133,21 +136,11 @@ internal XsdValidatingReader(XmlReader reader, XmlResolver xmlResolver, XmlReade _nsManager = new XmlNamespaceManager(_coreReaderNameTable); _manageNamespaces = true; } + _thisNSResolver = this as IXmlNamespaceResolver; _xmlResolver = xmlResolver; _processInlineSchema = (readerSettings.ValidationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0; - Init(); - SetupValidator(readerSettings, reader, partialValidationType); - _validationEvent = readerSettings.GetEventHandler(); - } - - internal XsdValidatingReader(XmlReader reader, XmlResolver xmlResolver, XmlReaderSettings readerSettings) - : - this(reader, xmlResolver, readerSettings, null) - { } - private void Init() - { _validationState = ValidatingReaderState.Init; _defaultAttributes = new ArrayList(); _currentAttrIndex = -1; @@ -156,7 +149,7 @@ private void Init() s_typeOfString = typeof(string); _xmlSchemaInfo = new XmlSchemaInfo(); - //Add common strings to be compared to NameTable + // Add common strings to be compared to NameTable _nsXmlNs = _coreReaderNameTable.Add(XmlReservedNs.NsXmlNs); _nsXs = _coreReaderNameTable.Add(XmlReservedNs.NsXs); _nsXsi = _coreReaderNameTable.Add(XmlReservedNs.NsXsi); @@ -165,20 +158,30 @@ private void Init() _xsiSchemaLocation = _coreReaderNameTable.Add("schemaLocation"); _xsiNoNamespaceSchemaLocation = _coreReaderNameTable.Add("noNamespaceSchemaLocation"); _xsdSchema = _coreReaderNameTable.Add("schema"); + + SetupValidator(readerSettings, reader, partialValidationType); + _validationEvent = readerSettings.GetEventHandler(); } - private void SetupValidator(XmlReaderSettings readerSettings, XmlReader reader, XmlSchemaObject partialValidationType) + internal XsdValidatingReader(XmlReader reader, XmlResolver? xmlResolver, XmlReaderSettings readerSettings) + : this(reader, xmlResolver, readerSettings, null) + { } + + [MemberNotNull("_validator")] + private void SetupValidator(XmlReaderSettings readerSettings, XmlReader reader, XmlSchemaObject? partialValidationType) { _validator = new XmlSchemaValidator(_coreReaderNameTable, readerSettings.Schemas, _thisNSResolver, readerSettings.ValidationFlags); _validator.XmlResolver = _xmlResolver; - _validator.SourceUri = XmlConvert.ToUri(reader.BaseURI); //Not using XmlResolver.ResolveUri as it checks for relative Uris,reader.BaseURI will be absolute file paths or string.Empty + _validator.SourceUri = XmlConvert.ToUri(reader.BaseURI); // Not using XmlResolver.ResolveUri as it checks for relative Uris,reader.BaseURI will be absolute file paths or string.Empty _validator.ValidationEventSender = this; _validator.ValidationEventHandler += readerSettings.GetEventHandler(); _validator.LineInfoProvider = _lineInfo; + if (_validator.ProcessSchemaHints) { _validator.SchemaSet.ReaderSettings.DtdProcessing = readerSettings.DtdProcessing; } + _validator.SetDtdSchemaInfo(reader.DtdInfo); if (partialValidationType != null) { @@ -195,13 +198,9 @@ public override XmlReaderSettings Settings { get { - XmlReaderSettings settings = _coreReader.Settings; - if (null != settings) - settings = settings.Clone(); - if (settings == null) - { - settings = new XmlReaderSettings(); - } + XmlReaderSettings? settings = _coreReader.Settings; + settings = settings != null ? settings.Clone() : new XmlReaderSettings(); + settings.Schemas = _validator.SchemaSet; settings.ValidationType = ValidationType.Schema; settings.ValidationFlags = _validator.ValidationFlags; @@ -219,16 +218,18 @@ public override XmlNodeType NodeType { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.NodeType; } else { XmlNodeType nodeType = _coreReader.NodeType; - //Check for significant whitespace + // Check for significant whitespace if (nodeType == XmlNodeType.Whitespace && (_validator.CurrentContentType == XmlSchemaContentType.TextOnly || _validator.CurrentContentType == XmlSchemaContentType.Mixed)) { return XmlNodeType.SignificantWhitespace; } + return nodeType; } } @@ -241,13 +242,16 @@ public override string Name { if (_validationState == ValidatingReaderState.OnDefaultAttribute) { + Debug.Assert(_cachedNode != null); string prefix = _validator.GetDefaultAttributePrefix(_cachedNode.Namespace); if (prefix != null && prefix.Length != 0) { return prefix + ":" + _cachedNode.LocalName; } + return _cachedNode.LocalName; } + return _coreReader.Name; } } @@ -259,8 +263,10 @@ public override string LocalName { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.LocalName; } + return _coreReader.LocalName; } } @@ -272,8 +278,10 @@ public override string NamespaceURI { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.Namespace; } + return _coreReader.NamespaceURI; } } @@ -285,8 +293,10 @@ public override string Prefix { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.Prefix; } + return _coreReader.Prefix; } } @@ -300,6 +310,7 @@ public override bool HasValue { return true; } + return _coreReader.HasValue; } } @@ -311,8 +322,10 @@ public override string Value { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.RawValue; } + return _coreReader.Value; } } @@ -324,14 +337,16 @@ public override int Depth { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.Depth; } + return _coreReader.Depth; } } // Gets the base URI of the current node. - public override string BaseURI + public override string? BaseURI { get { @@ -355,10 +370,12 @@ public override bool IsDefault get { if (_validationState == ValidatingReaderState.OnDefaultAttribute) - { //XSD default attributes + { + // XSD default attributes return true; } - return _coreReader.IsDefault; //This is DTD Default attribute + + return _coreReader.IsDefault; // This is DTD Default attribute } } @@ -407,15 +424,19 @@ public override System.Type ValueType case XmlNodeType.EndElement: if (_xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) { + Debug.Assert(_xmlSchemaInfo.SchemaType.Datatype != null); return _xmlSchemaInfo.SchemaType.Datatype.ValueType; } + goto default; case XmlNodeType.Attribute: if (_attributePSVI != null && AttributeSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) { + Debug.Assert(AttributeSchemaInfo.SchemaType.Datatype != null); return AttributeSchemaInfo.SchemaType.Datatype.ValueType; } + goto default; default: @@ -440,8 +461,9 @@ public override bool ReadContentAsBoolean() { throw CreateReadContentAsException(nameof(ReadContentAsBoolean)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -473,8 +495,9 @@ public override DateTime ReadContentAsDateTime() { throw CreateReadContentAsException(nameof(ReadContentAsDateTime)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -506,8 +529,9 @@ public override double ReadContentAsDouble() { throw CreateReadContentAsException(nameof(ReadContentAsDouble)); } - object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + + object? typedValue = InternalReadContentAsObject(); + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -539,8 +563,9 @@ public override float ReadContentAsFloat() { throw CreateReadContentAsException(nameof(ReadContentAsFloat)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -572,8 +597,9 @@ public override decimal ReadContentAsDecimal() { throw CreateReadContentAsException(nameof(ReadContentAsDecimal)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -605,8 +631,9 @@ public override int ReadContentAsInt() { throw CreateReadContentAsException(nameof(ReadContentAsInt)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -638,8 +665,10 @@ public override long ReadContentAsLong() { throw CreateReadContentAsException(nameof(ReadContentAsLong)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + try { if (xmlType != null) @@ -671,8 +700,10 @@ public override string ReadContentAsString() { throw CreateReadContentAsException(nameof(ReadContentAsString)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + try { if (xmlType != null) @@ -681,7 +712,7 @@ public override string ReadContentAsString() } else { - return typedValue as string; + return (typedValue as string)!; } } catch (InvalidCastException e) @@ -704,11 +735,10 @@ public override object ReadContentAs(Type returnType, IXmlNamespaceResolver name { throw CreateReadContentAsException(nameof(ReadContentAs)); } - string originalStringValue; + string originalStringValue; object typedValue = InternalReadContentAsObject(false, out originalStringValue); - - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -717,8 +747,9 @@ public override object ReadContentAs(Type returnType, IXmlNamespaceResolver name // which cannot preserve time zone, so we need to convert from the original string if (returnType == typeof(DateTimeOffset) && xmlType.Datatype is Datatype_dateTimeBase) { - typedValue = originalStringValue; + typedValue = originalStringValue!; } + return xmlType.ValueConverter.ChangeType(typedValue, returnType); } else @@ -746,9 +777,9 @@ public override object ReadElementContentAsObject() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsObject)); } - XmlSchemaType xmlType; - return InternalReadElementContentAsObject(out xmlType, true); + XmlSchemaType? xmlType; + return InternalReadElementContentAsObject(out xmlType, true)!; } public override bool ReadElementContentAsBoolean() @@ -757,9 +788,9 @@ public override bool ReadElementContentAsBoolean() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsBoolean)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -792,9 +823,9 @@ public override DateTime ReadElementContentAsDateTime() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsDateTime)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -827,9 +858,9 @@ public override double ReadElementContentAsDouble() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsDouble)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -862,9 +893,9 @@ public override float ReadElementContentAsFloat() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsFloat)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -897,9 +928,9 @@ public override decimal ReadElementContentAsDecimal() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsDecimal)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -932,9 +963,9 @@ public override int ReadElementContentAsInt() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsInt)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -967,9 +998,9 @@ public override long ReadElementContentAsLong() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsLong)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -1002,9 +1033,9 @@ public override string ReadElementContentAsString() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsString)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -1037,10 +1068,10 @@ public override object ReadElementContentAs(Type returnType, IXmlNamespaceResolv { throw CreateReadElementContentAsException(nameof(ReadElementContentAs)); } - XmlSchemaType xmlType; - string originalStringValue; - object typedValue = InternalReadElementContentAsObject(out xmlType, false, out originalStringValue); + XmlSchemaType? xmlType; + string? originalStringValue; + object? typedValue = InternalReadElementContentAsObject(out xmlType, false, out originalStringValue); try { @@ -1052,6 +1083,7 @@ public override object ReadElementContentAs(Type returnType, IXmlNamespaceResolv { typedValue = originalStringValue; } + return xmlType.ValueConverter.ChangeType(typedValue, returnType, namespaceResolver); } else @@ -1085,50 +1117,59 @@ public override int AttributeCount } // Gets the value of the attribute with the specified Name. - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { - string attValue = _coreReader.GetAttribute(name); + string? attValue = _coreReader.GetAttribute(name); if (attValue == null && _attributeCount > 0) - { //Could be default attribute - ValidatingReaderNodeData defaultNode = GetDefaultAttribute(name, false); + { + // Could be default attribute + ValidatingReaderNodeData? defaultNode = GetDefaultAttribute(name, false); if (defaultNode != null) - { //Default found + { + // Default found attValue = defaultNode.RawValue; } } + return attValue; } // Gets the value of the attribute with the specified LocalName and NamespaceURI. - public override string GetAttribute(string name, string namespaceURI) + public override string? GetAttribute(string name, string namespaceURI) { - string attValue = _coreReader.GetAttribute(name, namespaceURI); + string? attValue = _coreReader.GetAttribute(name, namespaceURI); if (attValue == null && _attributeCount > 0) - { //Could be default attribute - namespaceURI = (namespaceURI == null) ? string.Empty : _coreReaderNameTable.Get(namespaceURI); - name = _coreReaderNameTable.Get(name); - if (name == null || namespaceURI == null) - { //Attribute not present since we did not see it + { + // Could be default attribute + string? atomizedNamespaceURI = (namespaceURI == null) ? string.Empty : _coreReaderNameTable.Get(namespaceURI); + string? atomizedName = _coreReaderNameTable.Get(name); + + if (atomizedName == null || atomizedNamespaceURI == null) + { + // Attribute not present since we did not see it return null; } - ValidatingReaderNodeData attNode = GetDefaultAttribute(name, namespaceURI, false); + + ValidatingReaderNodeData? attNode = GetDefaultAttribute(atomizedName, atomizedNamespaceURI, false); if (attNode != null) { return attNode.RawValue; } } + return attValue; } // Gets the value of the attribute with the specified index. public override string GetAttribute(int i) { - if (_attributeCount == 0) + if (i < 0 || i >= _attributeCount) { - return null; + throw new ArgumentOutOfRangeException(nameof(i)); } + if (i < _coreReaderAttributeCount) { return _coreReader.GetAttribute(i); @@ -1136,7 +1177,7 @@ public override string GetAttribute(int i) else { int defaultIndex = i - _coreReaderAttributeCount; - ValidatingReaderNodeData attNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]; + ValidatingReaderNodeData attNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]!; Debug.Assert(attNode != null); return attNode.RawValue; } @@ -1152,8 +1193,9 @@ public override bool MoveToAttribute(string name) goto Found; } else if (_attributeCount > 0) - { //Default attribute - ValidatingReaderNodeData defaultNode = GetDefaultAttribute(name, true); + { + // Default attribute + ValidatingReaderNodeData? defaultNode = GetDefaultAttribute(name, true); if (defaultNode != null) { _validationState = ValidatingReaderState.OnDefaultAttribute; @@ -1162,43 +1204,52 @@ public override bool MoveToAttribute(string name) goto Found; } } + return false; Found: if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } + return true; } // Moves to the attribute with the specified LocalName and NamespaceURI - public override bool MoveToAttribute(string name, string ns) + public override bool MoveToAttribute(string name, string? ns) { - //Check atomized local name and ns - name = _coreReaderNameTable.Get(name); + // Check atomized local name and ns + string? atomizedName = _coreReaderNameTable.Get(name); ns = ns != null ? _coreReaderNameTable.Get(ns) : string.Empty; - if (name == null || ns == null) - { //Name or ns not found in the nameTable, then attribute is not found + + if (atomizedName == null || ns == null) + { + // Name or ns not found in the nameTable, then attribute is not found return false; } - if (_coreReader.MoveToAttribute(name, ns)) + + if (_coreReader.MoveToAttribute(atomizedName, ns)) { _validationState = ValidatingReaderState.OnAttribute; if (_inlineSchemaParser == null) { - _attributePSVI = GetAttributePSVI(name, ns); + _attributePSVI = GetAttributePSVI(atomizedName, ns); Debug.Assert(_attributePSVI != null); } else - { //Parsing inline schema, no PSVI for schema attributes + { + // Parsing inline schema, no PSVI for schema attributes _attributePSVI = null; } + goto Found; } else - { //Default attribute - ValidatingReaderNodeData defaultNode = GetDefaultAttribute(name, ns, true); + { + // Default attribute + ValidatingReaderNodeData? defaultNode = GetDefaultAttribute(atomizedName, ns, true); if (defaultNode != null) { _attributePSVI = defaultNode.AttInfo; @@ -1207,13 +1258,17 @@ public override bool MoveToAttribute(string name, string ns) goto Found; } } + return false; + Found: if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } + return true; } @@ -1224,9 +1279,11 @@ public override void MoveToAttribute(int i) { throw new ArgumentOutOfRangeException(nameof(i)); } + _currentAttrIndex = i; if (i < _coreReaderAttributeCount) - { //reader attribute + { + // reader attribute _coreReader.MoveToAttribute(i); if (_inlineSchemaParser == null) { @@ -1236,17 +1293,21 @@ public override void MoveToAttribute(int i) { _attributePSVI = null; } + _validationState = ValidatingReaderState.OnAttribute; } else - { //default attribute + { + // default attribute int defaultIndex = i - _coreReaderAttributeCount; - _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]; + _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]!; _attributePSVI = _cachedNode.AttInfo; _validationState = ValidatingReaderState.OnDefaultAttribute; } + if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } @@ -1266,24 +1327,29 @@ public override bool MoveToFirstAttribute() { _attributePSVI = null; } + _validationState = ValidatingReaderState.OnAttribute; goto Found; } else if (_defaultAttributes.Count > 0) - { //check for default - _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[0]; + { + // check for default + _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[0]!; _attributePSVI = _cachedNode.AttInfo; _currentAttrIndex = 0; _validationState = ValidatingReaderState.OnDefaultAttribute; goto Found; } + return false; Found: if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } + return true; } @@ -1303,24 +1369,29 @@ public override bool MoveToNextAttribute() { _attributePSVI = null; } + _validationState = ValidatingReaderState.OnAttribute; goto Found; } else if (_currentAttrIndex + 1 < _attributeCount) - { //default attribute + { + // default attribute int defaultIndex = ++_currentAttrIndex - _coreReaderAttributeCount; - _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]; + _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]!; _attributePSVI = _cachedNode.AttInfo; _validationState = ValidatingReaderState.OnDefaultAttribute; goto Found; } + return false; Found: if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } + return true; } @@ -1328,11 +1399,13 @@ public override bool MoveToNextAttribute() public override bool MoveToElement() { if (_coreReader.MoveToElement() || (int)_validationState < 0) - { //states OnDefaultAttribute or OnReadAttributeValue + { + // states OnDefaultAttribute or OnReadAttributeValue _currentAttrIndex = -1; _validationState = ValidatingReaderState.ClearAttributes; return true; } + return false; } @@ -1354,6 +1427,7 @@ public override bool Read() { _validationState = ValidatingReaderState.EOF; } + return false; } @@ -1377,7 +1451,7 @@ public override bool Read() goto case ValidatingReaderState.Read; } - case ValidatingReaderState.ReadAhead: //Will enter here on calling Skip() + case ValidatingReaderState.ReadAhead: // Will enter here on calling Skip() ClearAttributesInfo(); ProcessReaderEvent(); _validationState = ValidatingReaderState.Read; @@ -1385,13 +1459,15 @@ public override bool Read() case ValidatingReaderState.OnReadBinaryContent: _validationState = _savedState; + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); return Read(); case ValidatingReaderState.Init: _validationState = ValidatingReaderState.Read; if (_coreReader.ReadState == ReadState.Interactive) - { //If the underlying reader is already positioned on a ndoe, process it + { + // If the underlying reader is already positioned on a ndoe, process it ProcessReaderEvent(); return true; } @@ -1445,26 +1521,29 @@ public override void Skip() { break; } + bool callSkipToEndElem = true; - //If union and unionValue has been parsed till EndElement, then validator.ValidateEndElement has been called - //Hence should not call SkipToEndElement as the current context has already been popped in the validator + // If union and unionValue has been parsed till EndElement, then validator.ValidateEndElement has been called + // Hence should not call SkipToEndElement as the current context has already been popped in the validator if ((_xmlSchemaInfo.IsUnionType || _xmlSchemaInfo.IsDefault) && _coreReader is XsdCachingReader) { callSkipToEndElem = false; } + _coreReader.Skip(); _validationState = ValidatingReaderState.ReadAhead; if (callSkipToEndElem) { _validator.SkipToEndElement(_xmlSchemaInfo); } + break; case XmlNodeType.Attribute: MoveToElement(); goto case XmlNodeType.Element; } - //For all other NodeTypes Skip() same as Read() + // For all other NodeTypes Skip() same as Read() Read(); return; } @@ -1479,7 +1558,7 @@ public override XmlNameTable NameTable } // Resolves a namespace prefix in the current element's scope. - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { return _thisNSResolver.LookupNamespace(prefix); } @@ -1495,19 +1574,24 @@ public override bool ReadAttributeValue() { if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } + if (NodeType == XmlNodeType.Attribute) { if (_validationState == ValidatingReaderState.OnDefaultAttribute) { + Debug.Assert(_cachedNode != null); _cachedNode = CreateDummyTextNode(_cachedNode.RawValue, _cachedNode.Depth + 1); _validationState = ValidatingReaderState.OnReadAttributeValue; return true; } + return _coreReader.ReadAttributeValue(); } + return false; } @@ -1537,6 +1621,7 @@ public override int ReadContentAsBase64(byte[] buffer, int index, int count) _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = _readBinaryHelper.ReadContentAsBase64(buffer, index, count); // set OnReadBinaryContent state again and return @@ -1563,6 +1648,7 @@ public override int ReadContentAsBinHex(byte[] buffer, int index, int count) _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = _readBinaryHelper.ReadContentAsBinHex(buffer, index, count); // set OnReadBinaryContent state again and return @@ -1589,6 +1675,7 @@ public override int ReadElementContentAsBase64(byte[] buffer, int index, int cou _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = _readBinaryHelper.ReadElementContentAsBase64(buffer, index, count); // set OnReadBinaryContent state again and return @@ -1615,6 +1702,7 @@ public override int ReadElementContentAsBinHex(byte[] buffer, int index, int cou _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = _readBinaryHelper.ReadElementContentAsBinHex(buffer, index, count); // set OnReadBinaryContent state again and return @@ -1637,6 +1725,7 @@ bool IXmlSchemaInfo.IsDefault { GetIsDefault(); } + return _xmlSchemaInfo.IsDefault; case XmlNodeType.EndElement: @@ -1647,11 +1736,13 @@ bool IXmlSchemaInfo.IsDefault { return AttributeSchemaInfo.IsDefault; } + break; default: break; } + return false; } } @@ -1669,6 +1760,7 @@ bool IXmlSchemaInfo.IsNil default: break; } + return false; } } @@ -1684,10 +1776,13 @@ XmlSchemaValidity IXmlSchemaInfo.Validity { return _xmlSchemaInfo.Validity; } + if (_xmlSchemaInfo.Validity == XmlSchemaValidity.Valid) - { //It might be valid for unions since we read ahead, but report notknown for consistency + { + // It might be valid for unions since we read ahead, but report notknown for consistency return XmlSchemaValidity.NotKnown; } + return _xmlSchemaInfo.Validity; case XmlNodeType.EndElement: @@ -1698,13 +1793,15 @@ XmlSchemaValidity IXmlSchemaInfo.Validity { return AttributeSchemaInfo.Validity; } + break; } + return XmlSchemaValidity.NotKnown; } } - XmlSchemaSimpleType IXmlSchemaInfo.MemberType + XmlSchemaSimpleType? IXmlSchemaInfo.MemberType { get { @@ -1715,6 +1812,7 @@ XmlSchemaSimpleType IXmlSchemaInfo.MemberType { GetMemberType(); } + return _xmlSchemaInfo.MemberType; case XmlNodeType.EndElement: @@ -1725,15 +1823,16 @@ XmlSchemaSimpleType IXmlSchemaInfo.MemberType { return AttributeSchemaInfo.MemberType; } + return null; default: - return null; //Text, PI, Comment etc + return null; // Text, PI, Comment etc } } } - XmlSchemaType IXmlSchemaInfo.SchemaType + XmlSchemaType? IXmlSchemaInfo.SchemaType { get { @@ -1748,14 +1847,16 @@ XmlSchemaType IXmlSchemaInfo.SchemaType { return AttributeSchemaInfo.SchemaType; } + return null; default: - return null; //Text, PI, Comment etc + return null; // Text, PI, Comment etc } } } - XmlSchemaElement IXmlSchemaInfo.SchemaElement + + XmlSchemaElement? IXmlSchemaInfo.SchemaElement { get { @@ -1763,11 +1864,12 @@ XmlSchemaElement IXmlSchemaInfo.SchemaElement { return _xmlSchemaInfo.SchemaElement; } + return null; } } - XmlSchemaAttribute IXmlSchemaInfo.SchemaAttribute + XmlSchemaAttribute? IXmlSchemaInfo.SchemaAttribute { get { @@ -1778,6 +1880,7 @@ XmlSchemaAttribute IXmlSchemaInfo.SchemaAttribute return AttributeSchemaInfo.SchemaAttribute; } } + return null; } } @@ -1799,6 +1902,7 @@ public int LineNumber { return _lineInfo.LineNumber; } + return 0; } } @@ -1811,6 +1915,7 @@ public int LinePosition { return _lineInfo.LinePosition; } + return 0; } } @@ -1826,11 +1931,12 @@ public int LinePosition } else { + Debug.Assert(_nsManager != null); return _nsManager.GetNamespacesInScope(scope); } } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { if (_coreReaderNSResolver != null) { @@ -1838,11 +1944,12 @@ string IXmlNamespaceResolver.LookupNamespace(string prefix) } else { + Debug.Assert(_nsManager != null); return _nsManager.LookupNamespace(prefix); } } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { if (_coreReaderNSResolver != null) { @@ -1850,11 +1957,12 @@ string IXmlNamespaceResolver.LookupPrefix(string namespaceName) } else { + Debug.Assert(_nsManager != null); return _nsManager.LookupPrefix(namespaceName); } } - //Internal / Private methods + // Internal / Private methods private object GetStringValue() { @@ -1869,7 +1977,7 @@ private XmlSchemaType ElementXmlType } } - private XmlSchemaType AttributeXmlType + private XmlSchemaType? AttributeXmlType { get { @@ -1877,6 +1985,7 @@ private XmlSchemaType AttributeXmlType { return AttributeSchemaInfo.XmlType; } + return null; } } @@ -1893,11 +2002,13 @@ private XmlSchemaInfo AttributeSchemaInfo private void ProcessReaderEvent() { if (_replayCache) - { //if in replay mode, do nothing since nodes have been validated already - //If NodeType == XmlNodeType.EndElement && if manageNamespaces, may need to pop namespace scope, since scope is not popped in ReadAheadForMemberType + { + // if in replay mode, do nothing since nodes have been validated already + // If NodeType == XmlNodeType.EndElement && if manageNamespaces, may need to pop namespace scope, since scope is not popped in ReadAheadForMemberType return; } + switch (_coreReader.NodeType) { case XmlNodeType.Element: @@ -1943,7 +2054,8 @@ private void ProcessElementEvent() _xmlSchemaInfo.Clear(); _attributeCount = _coreReaderAttributeCount = _coreReader.AttributeCount; if (!_coreReader.IsEmptyElement) - { //If its not empty schema, then parse else ignore + { + // If its not empty schema, then parse else ignore _inlineSchemaParser = new Parser(SchemaType.XSD, _coreReaderNameTable, _validator.SchemaSet.GetSchemaNames(_coreReaderNameTable), _validationEvent); _inlineSchemaParser.StartParsing(_coreReader, null); _inlineSchemaParser.ParseReaderNode(); @@ -1955,27 +2067,32 @@ private void ProcessElementEvent() } } else - { //Validate element - //Clear previous data + { + // Validate element + // Clear previous data _atomicValue = null; _originalAtomicValueString = null; _xmlSchemaInfo.Clear(); if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PushScope(); } - //Find Xsi attributes that need to be processed before validating the element - string xsiSchemaLocation = null; - string xsiNoNamespaceSL = null; - string xsiNil = null; - string xsiType = null; + + // Find Xsi attributes that need to be processed before validating the element + string? xsiSchemaLocation = null; + string? xsiNoNamespaceSL = null; + string? xsiNil = null; + string? xsiType = null; + if (_coreReader.MoveToFirstAttribute()) { do { string objectNs = _coreReader.NamespaceURI; string objectName = _coreReader.LocalName; + if (Ref.Equal(objectNs, _nsXsi)) { if (Ref.Equal(objectName, _xsiSchemaLocation)) @@ -1995,13 +2112,16 @@ private void ProcessElementEvent() xsiNil = _coreReader.Value; } } + if (_manageNamespaces && Ref.Equal(_coreReader.NamespaceURI, _nsXmlNs)) { + Debug.Assert(_nsManager != null); _nsManager.AddNamespace(_coreReader.Prefix.Length == 0 ? string.Empty : _coreReader.LocalName, _coreReader.Value); } } while (_coreReader.MoveToNextAttribute()); _coreReader.MoveToElement(); } + _validator.ValidateElement(_coreReader.LocalName, _coreReader.NamespaceURI, _xmlSchemaInfo, xsiType, xsiNil, xsiSchemaLocation, xsiNoNamespaceSL); ValidateAttributes(); _validator.ValidateEndOfAttributes(_xmlSchemaInfo); @@ -2009,6 +2129,7 @@ private void ProcessElementEvent() { ProcessEndElementEvent(); } + _validationState = ValidatingReaderState.ClearAttributes; } } @@ -2018,10 +2139,12 @@ private void ProcessEndElementEvent() _atomicValue = _validator.ValidateEndElement(_xmlSchemaInfo); _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_xmlSchemaInfo.IsDefault) - { //The atomicValue returned is a default value + { + // The atomicValue returned is a default value Debug.Assert(_atomicValue != null); int depth = _coreReader.Depth; _coreReader = GetCachingReader(); + Debug.Assert(_cachingReader != null); _cachingReader.RecordTextNode(_xmlSchemaInfo.XmlType.ValueConverter.ToString(_atomicValue), _originalAtomicValueString, depth + 1, 0, 0); _cachingReader.RecordEndElementNode(); _cachingReader.SetToReplayMode(); @@ -2029,6 +2152,7 @@ private void ProcessEndElementEvent() } else if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PopScope(); } } @@ -2055,19 +2179,24 @@ private void ValidateAttributes() attIndex++; continue; } + attributePSVI.typedAttributeValue = _validator.ValidateAttribute(localName, ns, _valueGetter, attributePSVI.attributeSchemaInfo); if (!attributeInvalid) { attributeInvalid = attributePSVI.attributeSchemaInfo.Validity == XmlSchemaValidity.Invalid; } + attIndex++; } while (_coreReader.MoveToNextAttribute()); } + _coreReader.MoveToElement(); if (attributeInvalid) - { //If any of the attributes are invalid, Need to report element's validity as invalid + { + // If any of the attributes are invalid, Need to report element's validity as invalid _xmlSchemaInfo.Validity = XmlSchemaValidity.Invalid; } + _validator.GetUnspecifiedDefaultAttributes(_defaultAttributes, true); _attributeCount += _defaultAttributes.Count; } @@ -2081,12 +2210,14 @@ private void ClearAttributesInfo() _attributePSVI = null; } - private AttributePSVIInfo GetAttributePSVI(string name) + private AttributePSVIInfo? GetAttributePSVI(string name) { if (_inlineSchemaParser != null) - { //Parsing inline schema, no PSVI for schema attributes + { + // Parsing inline schema, no PSVI for schema attributes return null; } + string attrLocalName; string attrPrefix; string ns; @@ -2095,27 +2226,30 @@ private AttributePSVIInfo GetAttributePSVI(string name) attrLocalName = _coreReaderNameTable.Add(attrLocalName); if (attrPrefix.Length == 0) - { //empty prefix, not qualified + { + // empty prefix, not qualified ns = string.Empty; } else { - ns = _thisNSResolver.LookupNamespace(attrPrefix); + ns = _thisNSResolver.LookupNamespace(attrPrefix)!; } + return GetAttributePSVI(attrLocalName, ns); } - private AttributePSVIInfo GetAttributePSVI(string localName, string ns) + private AttributePSVIInfo? GetAttributePSVI(string localName, string ns) { Debug.Assert(_coreReaderNameTable.Get(localName) != null); Debug.Assert(_coreReaderNameTable.Get(ns) != null); - AttributePSVIInfo attInfo = null; + AttributePSVIInfo? attInfo = null; for (int i = 0; i < _coreReaderAttributeCount; i++) { attInfo = _attributePSVINodes[i]; if (attInfo != null) - { //Will be null for invalid attributes + { + // Will be null for invalid attributes if (Ref.Equal(localName, attInfo.localName) && Ref.Equal(ns, attInfo.namespaceUri)) { _currentAttrIndex = i; @@ -2123,16 +2257,17 @@ private AttributePSVIInfo GetAttributePSVI(string localName, string ns) } } } + return null; } - private ValidatingReaderNodeData GetDefaultAttribute(string name, bool updatePosition) + private ValidatingReaderNodeData? GetDefaultAttribute(string name, bool updatePosition) { string attrLocalName; string attrPrefix; ValidateNames.SplitQName(name, out attrPrefix, out attrLocalName); - //Atomize + // Atomize attrPrefix = _coreReaderNameTable.Add(attrPrefix); attrLocalName = _coreReaderNameTable.Add(attrLocalName); string ns; @@ -2142,29 +2277,32 @@ private ValidatingReaderNodeData GetDefaultAttribute(string name, bool updatePos } else { - ns = _thisNSResolver.LookupNamespace(attrPrefix); + ns = _thisNSResolver.LookupNamespace(attrPrefix)!; } + return GetDefaultAttribute(attrLocalName, ns, updatePosition); } - private ValidatingReaderNodeData GetDefaultAttribute(string attrLocalName, string ns, bool updatePosition) + private ValidatingReaderNodeData? GetDefaultAttribute(string attrLocalName, string ns, bool updatePosition) { Debug.Assert(_coreReaderNameTable.Get(attrLocalName) != null); Debug.Assert(_coreReaderNameTable.Get(ns) != null); - ValidatingReaderNodeData defaultNode = null; + ValidatingReaderNodeData? defaultNode = null; for (int i = 0; i < _defaultAttributes.Count; i++) { - defaultNode = (ValidatingReaderNodeData)_defaultAttributes[i]; + defaultNode = (ValidatingReaderNodeData)_defaultAttributes[i]!; if (Ref.Equal(defaultNode.LocalName, attrLocalName) && Ref.Equal(defaultNode.Namespace, ns)) { if (updatePosition) { _currentAttrIndex = _coreReader.AttributeCount + i; } + return defaultNode; } } + return null; } @@ -2177,18 +2315,22 @@ private AttributePSVIInfo AddAttributePSVI(int attIndex) attInfo.Reset(); return attInfo; } + if (attIndex >= _attributePSVINodes.Length - 1) - { //reached capacity of PSVIInfo array, Need to increase capacity to twice the initial + { + // reached capacity of PSVIInfo array, Need to increase capacity to twice the initial AttributePSVIInfo[] newPSVINodes = new AttributePSVIInfo[_attributePSVINodes.Length * 2]; Array.Copy(_attributePSVINodes, newPSVINodes, _attributePSVINodes.Length); _attributePSVINodes = newPSVINodes; } + attInfo = _attributePSVINodes[attIndex]; if (attInfo == null) { attInfo = new AttributePSVIInfo(); _attributePSVINodes[attIndex] = attInfo; } + return attInfo; } @@ -2207,9 +2349,11 @@ private void ProcessInlineSchema() _attributeCount = _coreReaderAttributeCount = _coreReader.AttributeCount; } else - { //Clear attributes info if nodeType is not element + { + // Clear attributes info if nodeType is not element ClearAttributesInfo(); } + if (!_inlineSchemaParser.ParseReaderNode()) { _inlineSchemaParser.FinishParsing(); @@ -2228,8 +2372,7 @@ private object InternalReadContentAsObject() private object InternalReadContentAsObject(bool unwrapTypedValue) { - string str; - return InternalReadContentAsObject(unwrapTypedValue, out str); + return InternalReadContentAsObject(unwrapTypedValue, out _); } private object InternalReadContentAsObject(bool unwrapTypedValue, out string originalStringValue) @@ -2246,10 +2389,11 @@ private object InternalReadContentAsObject(bool unwrapTypedValue, out string ori originalStringValue = (schemaAttr.DefaultValue != null) ? schemaAttr.DefaultValue : schemaAttr.FixedValue; } - return ReturnBoxedValue(_attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType, unwrapTypedValue); + return ReturnBoxedValue(_attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType, unwrapTypedValue)!; } else - { //return string value + { + // return string value return this.Value; } } @@ -2257,7 +2401,7 @@ private object InternalReadContentAsObject(bool unwrapTypedValue, out string ori { if (_atomicValue != null) { - originalStringValue = _originalAtomicValueString; + originalStringValue = _originalAtomicValueString!; return _atomicValue; } @@ -2269,18 +2413,19 @@ private object InternalReadContentAsObject(bool unwrapTypedValue, out string ori } } else - { //Positioned on text, CDATA, PI, Comment etc + { + // Positioned on text, CDATA, PI, Comment etc if (_validator.CurrentContentType == XmlSchemaContentType.TextOnly) - { //if current element is of simple type - object value = ReturnBoxedValue(ReadTillEndElement(), _xmlSchemaInfo.XmlType, unwrapTypedValue); - originalStringValue = _originalAtomicValueString; + { + // if current element is of simple type + object? value = ReturnBoxedValue(ReadTillEndElement(), _xmlSchemaInfo.XmlType, unwrapTypedValue)!; + originalStringValue = _originalAtomicValueString!; return value; } else { - XsdCachingReader cachingReader = _coreReader as XsdCachingReader; - if (cachingReader != null) + if (_coreReader is XsdCachingReader cachingReader) { originalStringValue = cachingReader.ReadOriginalContentAsString(); } @@ -2294,23 +2439,23 @@ private object InternalReadContentAsObject(bool unwrapTypedValue, out string ori } } - private object InternalReadElementContentAsObject(out XmlSchemaType xmlType) + private object? InternalReadElementContentAsObject(out XmlSchemaType? xmlType) { return InternalReadElementContentAsObject(out xmlType, false); } - private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, bool unwrapTypedValue) + private object? InternalReadElementContentAsObject(out XmlSchemaType? xmlType, bool unwrapTypedValue) { - string tmpString; - return InternalReadElementContentAsObject(out xmlType, unwrapTypedValue, out tmpString); + return InternalReadElementContentAsObject(out xmlType, unwrapTypedValue, out _); } - private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, bool unwrapTypedValue, out string originalString) + private object? InternalReadElementContentAsObject(out XmlSchemaType? xmlType, bool unwrapTypedValue, out string? originalString) { Debug.Assert(this.NodeType == XmlNodeType.Element); - object typedValue = null; + object? typedValue = null; xmlType = null; - //If its an empty element, can have default/fixed value + + // If its an empty element, can have default/fixed value if (this.IsEmptyElement) { if (_xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) @@ -2321,17 +2466,20 @@ private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, boo { typedValue = _atomicValue; } + originalString = _originalAtomicValueString; - xmlType = ElementXmlType; //Set this for default values + xmlType = ElementXmlType; // Set this for default values this.Read(); return typedValue; } + // move to content and read typed value this.Read(); if (this.NodeType == XmlNodeType.EndElement) - { //If IsDefault is true, the next node will be EndElement + { + // If IsDefault is true, the next node will be EndElement if (_xmlSchemaInfo.IsDefault) { if (_xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) @@ -2339,19 +2487,23 @@ private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, boo typedValue = ReturnBoxedValue(_atomicValue, _xmlSchemaInfo.XmlType, unwrapTypedValue); } else - { //anyType has default value + { + // anyType has default value typedValue = _atomicValue; } + originalString = _originalAtomicValueString; } else - { //Empty content + { + // Empty content typedValue = string.Empty; originalString = string.Empty; } } else if (this.NodeType == XmlNodeType.Element) - { //the first child is again element node + { + // the first child is again element node throw new XmlException(SR.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo); } else @@ -2364,7 +2516,8 @@ private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, boo throw new XmlException(SR.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo); } } - xmlType = ElementXmlType; //Set this as we are moving ahead to the next node + + xmlType = ElementXmlType; // Set this as we are moving ahead to the next node // move to next node this.Read(); @@ -2372,16 +2525,18 @@ private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, boo return typedValue; } - private object ReadTillEndElement() + private object? ReadTillEndElement() { if (_atomicValue == null) { while (_coreReader.Read()) { if (_replayCache) - { //If replaying nodes in the cache, they have already been validated + { + // If replaying nodes in the cache, they have already been validated continue; } + switch (_coreReader.NodeType) { case XmlNodeType.Element: @@ -2407,33 +2562,41 @@ private object ReadTillEndElement() _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PopScope(); } + goto breakWhile; } + continue; breakWhile: break; } } else - { //atomicValue != null, meaning already read ahead - Switch reader + { + // atomicValue != null, meaning already read ahead - Switch reader if (_atomicValue == this) - { //switch back invalid marker; dont need it since coreReader moved to endElement + { + // switch back invalid marker; dont need it since coreReader moved to endElement _atomicValue = null; } + SwitchReader(); } + return _atomicValue; } private void SwitchReader() { - XsdCachingReader cachingReader = _coreReader as XsdCachingReader; - if (cachingReader != null) - { //Switch back without going over the cached contents again. + if (_coreReader is XsdCachingReader cachingReader) + { + // Switch back without going over the cached contents again. _coreReader = cachingReader.GetCoreReader(); } + Debug.Assert(_coreReader.NodeType == XmlNodeType.EndElement); _replayCache = false; } @@ -2466,15 +2629,20 @@ private void ReadAheadForMemberType() _atomicValue = _validator.ValidateEndElement(_xmlSchemaInfo); //?? pop namespaceManager scope _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_atomicValue == null) - { //Invalid marker + { + // Invalid marker _atomicValue = this; } else if (_xmlSchemaInfo.IsDefault) - { //The atomicValue returned is a default value + { + // The atomicValue returned is a default value + Debug.Assert(_cachingReader != null); _cachingReader.SwitchTextNodeAndEndElement(_xmlSchemaInfo.XmlType.ValueConverter.ToString(_atomicValue), _originalAtomicValueString); } + goto breakWhile; } + continue; breakWhile: break; @@ -2483,12 +2651,15 @@ private void ReadAheadForMemberType() private void GetIsDefault() { - XsdCachingReader cachedReader = _coreReader as XsdCachingReader; + XsdCachingReader? cachedReader = _coreReader as XsdCachingReader; if (cachedReader == null && _xmlSchemaInfo.HasDefaultValue) - { //Get Isdefault + { + // Get Isdefault _coreReader = GetCachingReader(); + Debug.Assert(_cachingReader != null); if (_xmlSchemaInfo.IsUnionType && !_xmlSchemaInfo.IsNil) - { //If it also union, get the memberType as well + { + // If it also union, get the memberType as well ReadAheadForMemberType(); } else @@ -2519,9 +2690,11 @@ private void GetIsDefault() _atomicValue = _validator.ValidateEndElement(_xmlSchemaInfo); //?? pop namespaceManager scope _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_xmlSchemaInfo.IsDefault) - { //The atomicValue returned is a default value + { + // The atomicValue returned is a default value _cachingReader.SwitchTextNodeAndEndElement(_xmlSchemaInfo.XmlType.ValueConverter.ToString(_atomicValue), _originalAtomicValueString); } + break; default: @@ -2529,6 +2702,7 @@ private void GetIsDefault() } } } + _cachingReader.SetToReplayMode(); _replayCache = true; } @@ -2540,39 +2714,46 @@ private void GetMemberType() { return; } - XsdCachingReader cachedReader = _coreReader as XsdCachingReader; + + XsdCachingReader? cachedReader = _coreReader as XsdCachingReader; if (cachedReader == null && _xmlSchemaInfo.IsUnionType && !_xmlSchemaInfo.IsNil) { _coreReader = GetCachingReader(); + Debug.Assert(_cachingReader != null); ReadAheadForMemberType(); _cachingReader.SetToReplayMode(); _replayCache = true; } } - private object ReturnBoxedValue(object typedValue, XmlSchemaType xmlType, bool unWrap) + private object? ReturnBoxedValue(object? typedValue, XmlSchemaType xmlType, bool unWrap) { if (typedValue != null) { if (unWrap) - { //convert XmlAtomicValue[] to object[] for list of unions; The other cases return typed value of the valueType anyway + { + // convert XmlAtomicValue[] to object[] for list of unions; The other cases return typed value of the valueType anyway Debug.Assert(xmlType != null && xmlType.Datatype != null); if (xmlType.Datatype.Variety == XmlSchemaDatatypeVariety.List) { - Datatype_List listType = xmlType.Datatype as Datatype_List; + Datatype_List? listType = xmlType.Datatype as Datatype_List; + Debug.Assert(listType != null); if (listType.ItemType.Variety == XmlSchemaDatatypeVariety.Union) { typedValue = xmlType.ValueConverter.ChangeType(typedValue, xmlType.Datatype.ValueType, _thisNSResolver); } } } + return typedValue; } else - { //return the original string value of the element or attribute + { + // return the original string value of the element or attribute Debug.Assert(NodeType != XmlNodeType.Attribute); typedValue = _validator.GetConcatenatedValue(); } + return typedValue; } @@ -2586,6 +2767,7 @@ private XsdCachingReader GetCachingReader() { _cachingReader.Reset(_coreReader); } + _lineInfo = _cachingReader as IXmlLineInfo; return _cachingReader; } @@ -2596,6 +2778,7 @@ internal ValidatingReaderNodeData CreateDummyTextNode(string attributeValue, int { _textNode = new ValidatingReaderNodeData(XmlNodeType.Text); } + _textNode.Depth = depth; _textNode.RawValue = attributeValue; return _textNode; @@ -2603,7 +2786,7 @@ internal ValidatingReaderNodeData CreateDummyTextNode(string attributeValue, int internal void CachingCallBack(XsdCachingReader cachingReader) { - _coreReader = cachingReader.GetCoreReader(); //re-switch the core-reader after caching reader is done + _coreReader = cachingReader.GetCoreReader(); // re-switch the core-reader after caching reader is done _lineInfo = cachingReader.GetLineInfo(); _replayCache = false; } @@ -2622,6 +2805,7 @@ private string GetOriginalAtomicValueStringOfElement() { return _validator.GetConcatenatedValue(); } + return string.Empty; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs index 24b68ff01ddba..a9953d2873af4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.IO; using System.Text; using System.Xml.Schema; @@ -23,8 +24,10 @@ public override Task GetValueAsync() { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return Task.FromResult(_cachedNode.RawValue); } + return _coreReader.GetValueAsync(); } @@ -44,8 +47,9 @@ public override async Task ReadContentAsStringAsync() { throw CreateReadContentAsException(nameof(ReadContentAsString)); } + object typedValue = await InternalReadContentAsObjectAsync().ConfigureAwait(false); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -54,7 +58,7 @@ public override async Task ReadContentAsStringAsync() } else { - return typedValue as string; + return (typedValue as string)!; } } catch (InvalidCastException e) @@ -77,6 +81,7 @@ public override async Task ReadContentAsAsync(Type returnType, IXmlNames { throw CreateReadContentAsException(nameof(ReadContentAs)); } + string originalStringValue; var tuple_0 = await InternalReadContentAsObjectTupleAsync(false).ConfigureAwait(false); @@ -84,7 +89,7 @@ public override async Task ReadContentAsAsync(Type returnType, IXmlNames object typedValue = tuple_0.Item2; - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -95,6 +100,7 @@ public override async Task ReadContentAsAsync(Type returnType, IXmlNames { typedValue = originalStringValue; } + return xmlType.ValueConverter.ChangeType(typedValue, returnType); } else @@ -134,12 +140,13 @@ public override async Task ReadElementContentAsStringAsync() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsString)); } + XmlSchemaType xmlType; - var tuple_9 = await InternalReadElementContentAsObjectAsync().ConfigureAwait(false); - xmlType = tuple_9.Item1; + var content = await InternalReadElementContentAsObjectAsync().ConfigureAwait(false); + xmlType = content.Item1; - object typedValue = tuple_9.Item2; + object typedValue = content.Item2; try { @@ -149,6 +156,7 @@ public override async Task ReadElementContentAsStringAsync() } else { + Debug.Assert(false, $"{nameof(typedValue)} should never be null"); return typedValue as string; } } @@ -172,14 +180,15 @@ public override async Task ReadElementContentAsAsync(Type returnType, IX { throw CreateReadElementContentAsException(nameof(ReadElementContentAs)); } + XmlSchemaType xmlType; string originalStringValue; - var tuple_10 = await InternalReadElementContentAsObjectTupleAsync(false).ConfigureAwait(false); - xmlType = tuple_10.Item1; - originalStringValue = tuple_10.Item2; + var content = await InternalReadElementContentAsObjectTupleAsync(false).ConfigureAwait(false); + xmlType = content.Item1; + originalStringValue = content.Item2; - object typedValue = tuple_10.Item3; + object typedValue = content.Item3; try { @@ -191,6 +200,7 @@ public override async Task ReadElementContentAsAsync(Type returnType, IX { typedValue = originalStringValue; } + return xmlType.ValueConverter.ChangeType(typedValue, returnType, namespaceResolver); } else @@ -227,6 +237,7 @@ private Task ReadAsync_Read(Task task) { _validationState = ValidatingReaderState.EOF; } + return AsyncHelper.DoneTaskFalse; } } @@ -250,6 +261,7 @@ private async Task _ReadAsync_Read(Task task) { _validationState = ValidatingReaderState.EOF; } + return false; } } @@ -302,19 +314,21 @@ public override Task ReadAsync() goto case ValidatingReaderState.Read; } - case ValidatingReaderState.ReadAhead: //Will enter here on calling Skip() + case ValidatingReaderState.ReadAhead: // Will enter here on calling Skip() ClearAttributesInfo(); Task task = ProcessReaderEventAsync(); return ReadAsync_ReadAhead(task); case ValidatingReaderState.OnReadBinaryContent: _validationState = _savedState; + Debug.Assert(_readBinaryHelper != null); return _readBinaryHelper.FinishAsync().CallBoolTaskFuncWhenFinishAsync(thisRef => thisRef.ReadAsync(), this); case ValidatingReaderState.Init: _validationState = ValidatingReaderState.Read; if (_coreReader.ReadState == ReadState.Interactive) - { //If the underlying reader is already positioned on a ndoe, process it + { + // If the underlying reader is already positioned on a ndoe, process it return ProcessReaderEventAsync().ReturnTrueTaskWhenFinishAsync(); } else @@ -342,26 +356,29 @@ public override async Task SkipAsync() { break; } + bool callSkipToEndElem = true; - //If union and unionValue has been parsed till EndElement, then validator.ValidateEndElement has been called - //Hence should not call SkipToEndElement as the current context has already been popped in the validator + // If union and unionValue has been parsed till EndElement, then validator.ValidateEndElement has been called + // Hence should not call SkipToEndElement as the current context has already been popped in the validator if ((_xmlSchemaInfo.IsUnionType || _xmlSchemaInfo.IsDefault) && _coreReader is XsdCachingReader) { callSkipToEndElem = false; } + await _coreReader.SkipAsync().ConfigureAwait(false); _validationState = ValidatingReaderState.ReadAhead; if (callSkipToEndElem) { _validator.SkipToEndElement(_xmlSchemaInfo); } + break; case XmlNodeType.Attribute: MoveToElement(); goto case XmlNodeType.Element; } - //For all other NodeTypes Skip() same as Read() + // For all other NodeTypes Skip() same as Read() await ReadAsync().ConfigureAwait(false); return; } @@ -384,6 +401,7 @@ public override async Task ReadContentAsBase64Async(byte[] buffer, int inde _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = await _readBinaryHelper.ReadContentAsBase64Async(buffer, index, count).ConfigureAwait(false); // set OnReadBinaryContent state again and return @@ -410,6 +428,7 @@ public override async Task ReadContentAsBinHexAsync(byte[] buffer, int inde _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = await _readBinaryHelper.ReadContentAsBinHexAsync(buffer, index, count).ConfigureAwait(false); // set OnReadBinaryContent state again and return @@ -436,6 +455,7 @@ public override async Task ReadElementContentAsBase64Async(byte[] buffer, i _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = await _readBinaryHelper.ReadElementContentAsBase64Async(buffer, index, count).ConfigureAwait(false); // set OnReadBinaryContent state again and return @@ -462,6 +482,7 @@ public override async Task ReadElementContentAsBinHexAsync(byte[] buffer, i _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = await _readBinaryHelper.ReadElementContentAsBinHexAsync(buffer, index, count).ConfigureAwait(false); // set OnReadBinaryContent state again and return @@ -473,11 +494,13 @@ public override async Task ReadElementContentAsBinHexAsync(byte[] buffer, i private Task ProcessReaderEventAsync() { if (_replayCache) - { //if in replay mode, do nothing since nodes have been validated already - //If NodeType == XmlNodeType.EndElement && if manageNamespaces, may need to pop namespace scope, since scope is not popped in ReadAheadForMemberType + { + // if in replay mode, do nothing since nodes have been validated already + // If NodeType == XmlNodeType.EndElement && if manageNamespaces, may need to pop namespace scope, since scope is not popped in ReadAheadForMemberType return Task.CompletedTask; } + switch (_coreReader.NodeType) { case XmlNodeType.Element: @@ -523,7 +546,8 @@ private async Task ProcessElementEventAsync() _xmlSchemaInfo.Clear(); _attributeCount = _coreReaderAttributeCount = _coreReader.AttributeCount; if (!_coreReader.IsEmptyElement) - { //If its not empty schema, then parse else ignore + { + // If its not empty schema, then parse else ignore _inlineSchemaParser = new Parser(SchemaType.XSD, _coreReaderNameTable, _validator.SchemaSet.GetSchemaNames(_coreReaderNameTable), _validationEvent); await _inlineSchemaParser.StartParsingAsync(_coreReader, null).ConfigureAwait(false); _inlineSchemaParser.ParseReaderNode(); @@ -535,21 +559,25 @@ private async Task ProcessElementEventAsync() } } else - { //Validate element - //Clear previous data + { + // Validate element + // Clear previous data _atomicValue = null; _originalAtomicValueString = null; _xmlSchemaInfo.Clear(); if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PushScope(); } - //Find Xsi attributes that need to be processed before validating the element - string xsiSchemaLocation = null; - string xsiNoNamespaceSL = null; - string xsiNil = null; - string xsiType = null; + + // Find Xsi attributes that need to be processed before validating the element + string? xsiSchemaLocation = null; + string? xsiNoNamespaceSL = null; + string? xsiNil = null; + string? xsiType = null; + if (_coreReader.MoveToFirstAttribute()) { do @@ -575,13 +603,16 @@ private async Task ProcessElementEventAsync() xsiNil = _coreReader.Value; } } + if (_manageNamespaces && Ref.Equal(_coreReader.NamespaceURI, _nsXmlNs)) { + Debug.Assert(_nsManager != null); _nsManager.AddNamespace(_coreReader.Prefix.Length == 0 ? string.Empty : _coreReader.LocalName, _coreReader.Value); } } while (_coreReader.MoveToNextAttribute()); _coreReader.MoveToElement(); } + _validator.ValidateElement(_coreReader.LocalName, _coreReader.NamespaceURI, _xmlSchemaInfo, xsiType, xsiNil, xsiSchemaLocation, xsiNoNamespaceSL); ValidateAttributes(); _validator.ValidateEndOfAttributes(_xmlSchemaInfo); @@ -589,6 +620,7 @@ private async Task ProcessElementEventAsync() { await ProcessEndElementEventAsync().ConfigureAwait(false); } + _validationState = ValidatingReaderState.ClearAttributes; } } @@ -598,10 +630,12 @@ private async Task ProcessEndElementEventAsync() _atomicValue = _validator.ValidateEndElement(_xmlSchemaInfo); _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_xmlSchemaInfo.IsDefault) - { //The atomicValue returned is a default value + { + // The atomicValue returned is a default value Debug.Assert(_atomicValue != null); int depth = _coreReader.Depth; _coreReader = GetCachingReader(); + Debug.Assert(_cachingReader != null); _cachingReader.RecordTextNode(_xmlSchemaInfo.XmlType.ValueConverter.ToString(_atomicValue), _originalAtomicValueString, depth + 1, 0, 0); _cachingReader.RecordEndElementNode(); await _cachingReader.SetToReplayModeAsync().ConfigureAwait(false); @@ -609,6 +643,7 @@ private async Task ProcessEndElementEventAsync() } else if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PopScope(); } } @@ -623,9 +658,11 @@ private async Task ProcessInlineSchemaAsync() _attributeCount = _coreReaderAttributeCount = _coreReader.AttributeCount; } else - { //Clear attributes info if nodeType is not element + { + // Clear attributes info if nodeType is not element ClearAttributesInfo(); } + if (!_inlineSchemaParser.ParseReaderNode()) { _inlineSchemaParser.FinishParsing(); @@ -644,9 +681,8 @@ private Task InternalReadContentAsObjectAsync() private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValue) { - var tuple_11 = await InternalReadContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); - - return tuple_11.Item2; + var content = await InternalReadContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); + return content.Item2; } private async Task> InternalReadContentAsObjectTupleAsync(bool unwrapTypedValue) @@ -666,11 +702,12 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu originalStringValue = (schemaAttr.DefaultValue != null) ? schemaAttr.DefaultValue : schemaAttr.FixedValue; } - tuple = new Tuple(originalStringValue, ReturnBoxedValue(_attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType, unwrapTypedValue)); + tuple = new Tuple(originalStringValue, ReturnBoxedValue(_attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType, unwrapTypedValue)!); return tuple; } else - { //return string value + { + // return string value tuple = new Tuple(originalStringValue, this.Value); return tuple; } @@ -679,6 +716,7 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu { if (_atomicValue != null) { + Debug.Assert(_originalAtomicValueString != null); originalStringValue = _originalAtomicValueString; tuple = new Tuple(originalStringValue, _atomicValue); @@ -693,10 +731,15 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu } } else - { //Positioned on text, CDATA, PI, Comment etc + { + // Positioned on text, CDATA, PI, Comment etc if (_validator.CurrentContentType == XmlSchemaContentType.TextOnly) - { //if current element is of simple type - object value = ReturnBoxedValue(await ReadTillEndElementAsync().ConfigureAwait(false), _xmlSchemaInfo.XmlType, unwrapTypedValue); + { + // if current element is of simple type + object? value = ReturnBoxedValue(await ReadTillEndElementAsync().ConfigureAwait(false), _xmlSchemaInfo.XmlType, unwrapTypedValue)!; + Debug.Assert(value != null); + + Debug.Assert(_originalAtomicValueString != null); originalStringValue = _originalAtomicValueString; tuple = new Tuple(originalStringValue, value); @@ -704,7 +747,7 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu } else { - XsdCachingReader cachingReader = _coreReader as XsdCachingReader; + XsdCachingReader? cachingReader = _coreReader as XsdCachingReader; if (cachingReader != null) { originalStringValue = cachingReader.ReadOriginalContentAsString(); @@ -727,71 +770,77 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu private async Task> InternalReadElementContentAsObjectAsync(bool unwrapTypedValue) { - var tuple_13 = await InternalReadElementContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); + var content = await InternalReadElementContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); - return new Tuple(tuple_13.Item1, tuple_13.Item3); + return new Tuple(content.Item1, content.Item3); } private async Task> InternalReadElementContentAsObjectTupleAsync(bool unwrapTypedValue) { - Tuple tuple; - XmlSchemaType xmlType; + XmlSchemaType? xmlType = null; string originalString; Debug.Assert(this.NodeType == XmlNodeType.Element); - object typedValue = null; - xmlType = null; - //If its an empty element, can have default/fixed value + object typedValue; + // If its an empty element, can have default/fixed value if (this.IsEmptyElement) { if (_xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) { - typedValue = ReturnBoxedValue(_atomicValue, _xmlSchemaInfo.XmlType, unwrapTypedValue); + typedValue = ReturnBoxedValue(_atomicValue, _xmlSchemaInfo.XmlType, unwrapTypedValue)!; } else { - typedValue = _atomicValue; + typedValue = _atomicValue!; } + + Debug.Assert(_originalAtomicValueString != null); originalString = _originalAtomicValueString; - xmlType = ElementXmlType; //Set this for default values + xmlType = ElementXmlType; // Set this for default values await this.ReadAsync().ConfigureAwait(false); - tuple = new Tuple(xmlType, originalString, typedValue); - return tuple; + return new Tuple(xmlType, originalString, typedValue); } + // move to content and read typed value await this.ReadAsync().ConfigureAwait(false); if (this.NodeType == XmlNodeType.EndElement) - { //If IsDefault is true, the next node will be EndElement + { + // If IsDefault is true, the next node will be EndElement if (_xmlSchemaInfo.IsDefault) { if (_xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) { - typedValue = ReturnBoxedValue(_atomicValue, _xmlSchemaInfo.XmlType, unwrapTypedValue); + typedValue = ReturnBoxedValue(_atomicValue, _xmlSchemaInfo.XmlType, unwrapTypedValue)!; } else - { //anyType has default value - typedValue = _atomicValue; + { + // anyType has default value + typedValue = _atomicValue!; } + + Debug.Assert(_originalAtomicValueString != null); originalString = _originalAtomicValueString; } else - { //Empty content + { + // Empty content typedValue = string.Empty; originalString = string.Empty; } } else if (this.NodeType == XmlNodeType.Element) - { //the first child is again element node + { + // the first child is again element node throw new XmlException(SR.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo); } else { - var tuple_14 = await InternalReadContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); - originalString = tuple_14.Item1; + var content = await InternalReadContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); + originalString = content.Item1; - typedValue = tuple_14.Item2; + typedValue = content.Item2; // ReadElementContentAsXXX cannot be called on mixed content, if positioned on node other than EndElement, Error if (this.NodeType != XmlNodeType.EndElement) @@ -799,25 +848,27 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu throw new XmlException(SR.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo); } } - xmlType = ElementXmlType; //Set this as we are moving ahead to the next node + + xmlType = ElementXmlType; // Set this as we are moving ahead to the next node // move to next node await this.ReadAsync().ConfigureAwait(false); - tuple = new Tuple(xmlType, originalString, typedValue); - return tuple; + return new Tuple(xmlType, originalString, typedValue); } - private async Task ReadTillEndElementAsync() + private async Task ReadTillEndElementAsync() { if (_atomicValue == null) { while (await _coreReader.ReadAsync().ConfigureAwait(false)) { if (_replayCache) - { //If replaying nodes in the cache, they have already been validated + { + // If replaying nodes in the cache, they have already been validated continue; } + switch (_coreReader.NodeType) { case XmlNodeType.Element: @@ -843,23 +894,30 @@ private async Task ReadTillEndElementAsync() _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PopScope(); } + goto breakWhile; } + continue; breakWhile: break; } } else - { //atomicValue != null, meaning already read ahead - Switch reader + { + // atomicValue != null, meaning already read ahead - Switch reader if (_atomicValue == this) - { //switch back invalid marker; dont need it since coreReader moved to endElement + { + // switch back invalid marker; dont need it since coreReader moved to endElement _atomicValue = null; } + SwitchReader(); } + return _atomicValue; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/AutoValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/AutoValidator.cs index 4ae13d948b817..70f9dfa5833f3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/AutoValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/AutoValidator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { using System.Diagnostics; @@ -43,7 +44,7 @@ public override void Validate() public override void CompleteValidation() { } - public override object FindId(string name) + public override object? FindId(string name) { return null; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs index c9f730028286f..237d763960885 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { using System.IO; @@ -9,25 +10,26 @@ namespace System.Xml.Schema using System.Xml; using System.Text; using System.Collections; + using System.Diagnostics.CodeAnalysis; #pragma warning disable 618 internal class BaseValidator { - private readonly XmlSchemaCollection _schemaCollection; + private readonly XmlSchemaCollection? _schemaCollection; private readonly IValidationEventHandling _eventHandling; private readonly XmlNameTable _nameTable; - private SchemaNames _schemaNames; + private SchemaNames? _schemaNames; private readonly PositionInfo _positionInfo; - private XmlResolver _xmlResolver; - private Uri _baseUri; + private XmlResolver? _xmlResolver; + private Uri? _baseUri; - protected SchemaInfo schemaInfo; + protected SchemaInfo? schemaInfo; protected XmlValidatingReaderImpl reader; protected XmlQualifiedName elementName; - protected ValidationState context; - protected StringBuilder textValue; - protected string textString; + protected ValidationState? context; + protected StringBuilder? textValue; + protected string? textString; protected bool hasSibling; protected bool checkDatatype; @@ -44,7 +46,7 @@ public BaseValidator(BaseValidator other) elementName = other.elementName; } - public BaseValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection schemaCollection, IValidationEventHandling eventHandling) + public BaseValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection? schemaCollection, IValidationEventHandling eventHandling) { Debug.Assert(schemaCollection == null || schemaCollection.NameTable == reader.NameTable); this.reader = reader; @@ -60,7 +62,7 @@ public XmlValidatingReaderImpl Reader get { return reader; } } - public XmlSchemaCollection SchemaCollection + public XmlSchemaCollection? SchemaCollection { get { return _schemaCollection; } } @@ -78,6 +80,7 @@ public SchemaNames SchemaNames { return _schemaNames; } + if (_schemaCollection != null) { _schemaNames = _schemaCollection.GetSchemaNames(_nameTable); @@ -86,6 +89,7 @@ public SchemaNames SchemaNames { _schemaNames = new SchemaNames(_nameTable); } + return _schemaNames; } } @@ -95,13 +99,13 @@ public PositionInfo PositionInfo get { return _positionInfo; } } - public XmlResolver XmlResolver + public XmlResolver? XmlResolver { get { return _xmlResolver; } set { _xmlResolver = value; } } - public Uri BaseUri + public Uri? BaseUri { get { return _baseUri; } set { _baseUri = value; } @@ -112,7 +116,7 @@ public ValidationEventHandler EventHandler get { return (ValidationEventHandler)_eventHandling.EventHandler; } } - public SchemaInfo SchemaInfo + public SchemaInfo? SchemaInfo { get { @@ -124,7 +128,8 @@ public SchemaInfo SchemaInfo } } - public IDtdInfo DtdInfo + [DisallowNull] + public IDtdInfo? DtdInfo { get { @@ -132,11 +137,12 @@ public IDtdInfo DtdInfo } set { - SchemaInfo tmpSchemaInfo = value as SchemaInfo; + SchemaInfo? tmpSchemaInfo = value as SchemaInfo; if (tmpSchemaInfo == null) { throw new XmlException(SR.Xml_InternalError, string.Empty); } + this.schemaInfo = tmpSchemaInfo; } } @@ -157,13 +163,14 @@ public virtual void CompleteValidation() { } - public virtual object FindId(string name) + public virtual object? FindId(string name) { return null; } public void ValidateText() { + Debug.Assert(context != null); if (context.NeedValidateChildren) { if (context.IsNill) @@ -171,6 +178,7 @@ public void ValidateText() SendValidationEvent(SR.Sch_ContentInNill, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); return; } + ContentValidator contentValidator = context.ElementDecl.ContentValidator; XmlSchemaContentType contentType = contentValidator.ContentType; if (contentType == XmlSchemaContentType.ElementOnly) @@ -190,6 +198,7 @@ public void ValidateText() { SendValidationEvent(SR.Sch_InvalidTextInEmpty, string.Empty); } + if (checkDatatype) { SaveTextValue(reader.Value); @@ -199,6 +208,7 @@ public void ValidateText() public void ValidateWhitespace() { + Debug.Assert(context != null); if (context.NeedValidateChildren) { XmlSchemaContentType contentType = context.ElementDecl.ContentValidator.ContentType; @@ -206,10 +216,12 @@ public void ValidateWhitespace() { SendValidationEvent(SR.Sch_ContentInNill, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); } + if (contentType == XmlSchemaContentType.Empty) { SendValidationEvent(SR.Sch_InvalidWhitespaceInEmpty, string.Empty); } + if (checkDatatype) { SaveTextValue(reader.Value); @@ -219,17 +231,20 @@ public void ValidateWhitespace() private void SaveTextValue(string value) { + Debug.Assert(textString != null); if (textString.Length == 0) { textString = value; } else { + Debug.Assert(textValue != null); if (!hasSibling) { textValue.Append(textString); hasSibling = true; } + textValue.Append(value); } } @@ -278,8 +293,8 @@ protected void SendValidationEvent(XmlSchemaException e, XmlSeverityType severit protected static void ProcessEntity(SchemaInfo sinfo, string name, object sender, ValidationEventHandler eventhandler, string baseUri, int lineNumber, int linePosition) { - SchemaEntity en; - XmlSchemaException e = null; + SchemaEntity? en; + XmlSchemaException? e = null; if (!sinfo.GeneralEntities.TryGetValue(new XmlQualifiedName(name), out en)) { // validation error, see xml spec [68] @@ -289,6 +304,7 @@ protected static void ProcessEntity(SchemaInfo sinfo, string name, object sender { e = new XmlSchemaException(SR.Sch_UnparsedEntityRef, name, baseUri, lineNumber, linePosition); } + if (e != null) { if (eventhandler != null) @@ -304,8 +320,8 @@ protected static void ProcessEntity(SchemaInfo sinfo, string name, object sender protected static void ProcessEntity(SchemaInfo sinfo, string name, IValidationEventHandling eventHandling, string baseUriStr, int lineNumber, int linePosition) { - SchemaEntity en; - string errorResId = null; + SchemaEntity? en; + string? errorResId = null; if (!sinfo.GeneralEntities.TryGetValue(new XmlQualifiedName(name), out en)) { // validation error, see xml spec [68] @@ -330,7 +346,7 @@ protected static void ProcessEntity(SchemaInfo sinfo, string name, IValidationEv } } - public static BaseValidator CreateInstance(ValidationType valType, XmlValidatingReaderImpl reader, XmlSchemaCollection schemaCollection, IValidationEventHandling eventHandling, bool processIdentityConstraints) + public static BaseValidator? CreateInstance(ValidationType valType, XmlValidatingReaderImpl reader, XmlSchemaCollection schemaCollection, IValidationEventHandling eventHandling, bool processIdentityConstraints) { switch (valType) { @@ -352,6 +368,7 @@ public static BaseValidator CreateInstance(ValidationType valType, XmlValidating default: break; } + return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs index cdcf3fec2d59b..6a93ab0365366 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Resources; @@ -29,15 +30,15 @@ public XmlSchemaInferenceException() : base(null) { } - public XmlSchemaInferenceException(string message) : base(message, ((Exception)null), 0, 0) + public XmlSchemaInferenceException(string message) : base(message, ((Exception?)null), 0, 0) { } - public XmlSchemaInferenceException(string message, Exception innerException) : base(message, innerException, 0, 0) + public XmlSchemaInferenceException(string message, Exception? innerException) : base(message, innerException, 0, 0) { } - public XmlSchemaInferenceException(string message, Exception innerException, int lineNumber, int linePosition) : + public XmlSchemaInferenceException(string message, Exception? innerException, int lineNumber, int linePosition) : base(message, innerException, lineNumber, linePosition) { } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs index 50e33a20c7625..c70077e05c69d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections; using System.ComponentModel; using System.Xml.Serialization; @@ -13,15 +14,15 @@ namespace System.Xml.Schema /// public class XmlSchemaType : XmlSchemaAnnotated { - private string _name; + private string? _name; private XmlSchemaDerivationMethod _final = XmlSchemaDerivationMethod.None; private XmlSchemaDerivationMethod _derivedBy; - private XmlSchemaType _baseSchemaType; - private XmlSchemaDatatype _datatype; + private XmlSchemaType? _baseSchemaType; + private XmlSchemaDatatype? _datatype; private XmlSchemaDerivationMethod _finalResolved; - private volatile SchemaElementDecl _elementDecl; + private volatile SchemaElementDecl? _elementDecl; private volatile XmlQualifiedName _qname = XmlQualifiedName.Empty; - private XmlSchemaType _redefined; + private XmlSchemaType? _redefined; //compiled information private XmlSchemaContentType _contentType; @@ -35,6 +36,7 @@ public static XmlSchemaSimpleType GetBuiltInSimpleType(XmlQualifiedName qualifie { throw new ArgumentNullException(nameof(qualifiedName)); } + return DatatypeImplementation.GetSimpleTypeFromXsdType(qualifiedName); } @@ -49,32 +51,36 @@ public static XmlSchemaSimpleType GetBuiltInSimpleType(XmlTypeCode typeCode) /// /// [To be supplied.] /// - public static XmlSchemaComplexType GetBuiltInComplexType(XmlTypeCode typeCode) + public static XmlSchemaComplexType? GetBuiltInComplexType(XmlTypeCode typeCode) { if (typeCode == XmlTypeCode.Item) { return XmlSchemaComplexType.AnyType; } + return null; } /// /// [To be supplied.] /// - public static XmlSchemaComplexType GetBuiltInComplexType(XmlQualifiedName qualifiedName) + public static XmlSchemaComplexType? GetBuiltInComplexType(XmlQualifiedName qualifiedName) { if (qualifiedName == null) { throw new ArgumentNullException(nameof(qualifiedName)); } + if (qualifiedName.Equals(XmlSchemaComplexType.AnyType.QualifiedName)) { return XmlSchemaComplexType.AnyType; } + if (qualifiedName.Equals(XmlSchemaComplexType.UntypedAnyType.QualifiedName)) { return XmlSchemaComplexType.UntypedAnyType; } + return null; } @@ -82,7 +88,7 @@ public static XmlSchemaComplexType GetBuiltInComplexType(XmlQualifiedName qualif /// [To be supplied.] /// [XmlAttribute("name")] - public string Name + public string? Name { get { return _name; } set { _name = value; } @@ -121,7 +127,7 @@ public XmlSchemaDerivationMethod FinalResolved /// [XmlIgnore] [Obsolete("This property has been deprecated. Please use BaseXmlSchemaType property that returns a strongly typed base schema type. https://go.microsoft.com/fwlink/?linkid=14202")] - public object BaseSchemaType + public object? BaseSchemaType { get { @@ -132,6 +138,7 @@ public object BaseSchemaType { return _baseSchemaType.Datatype; } + return _baseSchemaType; } } @@ -140,7 +147,7 @@ public object BaseSchemaType /// [To be supplied.] /// [XmlIgnore] - public XmlSchemaType BaseXmlSchemaType + public XmlSchemaType? BaseXmlSchemaType { get { return _baseSchemaType; } } @@ -158,7 +165,7 @@ public XmlSchemaDerivationMethod DerivedBy /// [To be supplied.] /// [XmlIgnore] - public XmlSchemaDatatype Datatype + public XmlSchemaDatatype? Datatype { get { return _datatype; } } @@ -203,7 +210,7 @@ internal XmlValueConverter ValueConverter } } - internal XmlReader Validate(XmlReader reader, XmlResolver resolver, XmlSchemaSet schemaSet, ValidationEventHandler valEventHandler) + internal XmlReader? Validate(XmlReader reader, XmlResolver resolver, XmlSchemaSet schemaSet, ValidationEventHandler valEventHandler) { if (schemaSet != null) { @@ -213,6 +220,7 @@ internal XmlReader Validate(XmlReader reader, XmlResolver resolver, XmlSchemaSet readerSettings.ValidationEventHandler += valEventHandler; return new XsdValidatingReader(reader, resolver, readerSettings, this); } + return null; } @@ -249,14 +257,14 @@ internal void SetDatatype(XmlSchemaDatatype value) _datatype = value; } - internal SchemaElementDecl ElementDecl + internal SchemaElementDecl? ElementDecl { get { return _elementDecl; } set { _elementDecl = value; } } [XmlIgnore] - internal XmlSchemaType Redefined + internal XmlSchemaType? Redefined { get { return _redefined; } set { _redefined = value; } @@ -272,7 +280,7 @@ internal void SetContentType(XmlSchemaContentType value) _contentType = value; } - public static bool IsDerivedFrom(XmlSchemaType derivedType, XmlSchemaType baseType, XmlSchemaDerivationMethod except) + public static bool IsDerivedFrom(XmlSchemaType? derivedType, XmlSchemaType? baseType, XmlSchemaDerivationMethod except) { if (derivedType == null || baseType == null) { @@ -288,17 +296,19 @@ public static bool IsDerivedFrom(XmlSchemaType derivedType, XmlSchemaType baseTy { //Not checking for restriction blocked since all types are implicitly derived by restriction from xs:anyType return true; } + do { - XmlSchemaSimpleType dt = derivedType as XmlSchemaSimpleType; - XmlSchemaSimpleType bt = baseType as XmlSchemaSimpleType; + XmlSchemaSimpleType? dt = derivedType as XmlSchemaSimpleType; + XmlSchemaSimpleType? bt = baseType as XmlSchemaSimpleType; if (bt != null && dt != null) { //SimpleTypes if (bt == DatatypeImplementation.AnySimpleType) { //Not checking block=restriction return true; } - if ((except & derivedType.DerivedBy) != 0 || !dt.Datatype.IsDerivedFrom(bt.Datatype)) + + if ((except & derivedType.DerivedBy) != 0 || !dt.Datatype!.IsDerivedFrom(bt.Datatype)) { return false; } @@ -310,6 +320,7 @@ public static bool IsDerivedFrom(XmlSchemaType derivedType, XmlSchemaType baseTy { return false; } + derivedType = derivedType.BaseXmlSchemaType; if (derivedType == baseType) { @@ -332,7 +343,7 @@ internal static bool IsDerivedFromDatatype(XmlSchemaDatatype derivedDataType, Xm } [XmlIgnore] - internal override string NameAttribute + internal override string? NameAttribute { get { return Name; } set { Name = value; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaUse.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaUse.cs index b39996f93f58b..3f320dfdd3699 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaUse.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaUse.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { using System.Xml.Serialization; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs index d751e088b866d..00f3c76b63e99 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs @@ -735,6 +735,7 @@ public void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes) { throw new ArgumentNullException(nameof(defaultAttributes)); } + CheckStateTransition(ValidatorState.Attribute, "GetUnspecifiedDefaultAttributes"); GetUnspecifiedDefaultAttributes(defaultAttributes, false); } @@ -1066,6 +1067,7 @@ internal void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes, bool continue; } } + XmlSchemaDatatype datatype = attdef.Datatype; if (createNodeData) { @@ -1090,6 +1092,7 @@ internal void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes, bool { attrValidInfo.typedAttributeValue = attdef.DefaultValueTyped; } + attSchemaInfo.IsDefault = true; attSchemaInfo.Validity = XmlSchemaValidity.Valid; attSchemaInfo.SchemaType = attdef.SchemaType; @@ -1103,6 +1106,7 @@ internal void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes, bool { defaultAttributes.Add(attdef.SchemaAttribute); } + CheckTokenizedTypes(datatype, attdef.DefaultValueTyped, true); if (HasIdentityConstraints) { @@ -1111,7 +1115,6 @@ internal void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes, bool } } } - return; } internal XmlSchemaSet SchemaSet diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidity.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidity.cs index 6c3aaa9c82c27..2902fee222562 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidity.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidity.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { public enum XmlSchemaValidity diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSeverityType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSeverityType.cs index d5d74ec1ab190..2fc305eff8e0d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSeverityType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSeverityType.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { //UE Atention diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTokenizedType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTokenizedType.cs index 9277fd46ce54c..26c3b874d8a50 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTokenizedType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTokenizedType.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml { // NOTE: Absolute numbering is utilized in DtdParser. -HelenaK diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTypeCode.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTypeCode.cs index 43ad4c8e3c98d..c39a138c968c5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTypeCode.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTypeCode.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { public enum XmlTypeCode diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdDuration.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdDuration.cs index 9a73084017a7c..4567d8d119911 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdDuration.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdDuration.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { using System; @@ -40,7 +41,7 @@ public enum DurationType Duration, YearMonthDuration, DayTimeDuration, - }; + } /// /// Construct an XsdDuration from component parts. @@ -143,11 +144,12 @@ public XsdDuration(string s) : this(s, DurationType.Duration) public XsdDuration(string s, DurationType durationType) { XsdDuration result; - Exception exception = TryParse(s, durationType, out result); + Exception? exception = TryParse(s, durationType, out result); if (exception != null) { throw exception; } + _years = result.Years; _months = result.Months; _days = result.Days; @@ -159,6 +161,7 @@ public XsdDuration(string s, DurationType durationType) { _nanoseconds |= NegativeBit; } + return; } @@ -242,22 +245,23 @@ public TimeSpan ToTimeSpan() public TimeSpan ToTimeSpan(DurationType durationType) { TimeSpan result; - Exception exception = TryToTimeSpan(durationType, out result); + Exception? exception = TryToTimeSpan(durationType, out result); if (exception != null) { throw exception; } + return result; } - internal Exception TryToTimeSpan(out TimeSpan result) + internal Exception? TryToTimeSpan(out TimeSpan result) { return TryToTimeSpan(DurationType.Duration, out result); } - internal Exception TryToTimeSpan(DurationType durationType, out TimeSpan result) + internal Exception? TryToTimeSpan(DurationType durationType, out TimeSpan result) { - Exception exception = null; + Exception? exception = null; ulong ticks = 0; // Throw error if result cannot fit into a long @@ -426,14 +430,14 @@ internal string ToString(DurationType durationType) return sb.ToString(); } - internal static Exception TryParse(string s, out XsdDuration result) + internal static Exception? TryParse(string s, out XsdDuration result) { return TryParse(s, DurationType.Duration, out result); } - internal static Exception TryParse(string s, DurationType durationType, out XsdDuration result) + internal static Exception? TryParse(string s, DurationType durationType, out XsdDuration result) { - string errorCode; + string? errorCode; int length; int value, pos, numDigits; Parts parts = Parts.HasNone; @@ -605,6 +609,7 @@ internal static Exception TryParse(string s, DurationType durationType, out XsdD if ((parts & ~(XsdDuration.Parts.HasYears | XsdDuration.Parts.HasMonths)) != 0) goto InvalidFormat; } + return null; InvalidFormat: @@ -619,7 +624,7 @@ internal static Exception TryParse(string s, DurationType durationType, out XsdD /// cntDigits. The integer is returned (0 if no digits). If the digits cannot fit into an Int32: /// 1. If eatDigits is true, then additional digits will be silently discarded (don't count towards numDigits) /// 2. If eatDigits is false, an overflow exception is thrown - private static string TryParseDigits(string s, ref int offset, bool eatDigits, out int result, out int numDigits) + private static string? TryParseDigits(string s, ref int offset, bool eatDigits, out int result, out int numDigits) { int offsetStart = offset; int offsetEnd = s.Length;