From 41ce8c0835651958df67937f50c26bae16e6e45e Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Wed, 22 Apr 2020 17:35:37 -0700 Subject: [PATCH] Nullable: System.Xml, part 1 --- .../System.Private.Xml/src/Misc/HResults.cs | 1 + .../src/System/Xml/BinaryXml/BinXmlToken.cs | 3 +- .../src/System/Xml/BinaryXml/SqlUtils.cs | 15 +- .../src/System/Xml/BinaryXml/XmlBinaryReader.cs | 157 +++--- .../System/Xml/Core/CharEntityEncoderFallback.cs | 7 +- .../src/System/Xml/Core/ConformanceLevel.cs | 1 + .../src/System/Xml/Core/DtdProcessing.cs | 1 + .../src/System/Xml/Core/EntityHandling.cs | 1 + .../src/System/Xml/Core/HtmlTernaryTree.cs | 1 + .../src/System/Xml/Core/IDtdInfo.cs | 3 +- .../src/System/Xml/Core/IDtdParser.cs | 1 + .../src/System/Xml/Core/IDtdParserAdapter.cs | 11 +- .../src/System/Xml/Core/IDtdParserAdapterAsync.cs | 1 + .../src/System/Xml/Core/IDtdParserAsync.cs | 1 + .../src/System/Xml/Core/NewLineHandling.cs | 1 + .../src/System/Xml/Core/ReadState.cs | 1 + .../src/System/Xml/Core/ValidationType.cs | 1 + .../src/System/Xml/Core/WhitespaceHandling.cs | 1 + .../src/System/Xml/Core/XmlParserContext.cs | 25 +- .../src/System/Xml/Core/XmlReader.cs | 77 ++- .../src/System/Xml/Core/XmlReaderAsync.cs | 3 +- .../src/System/Xml/Core/XmlReaderSettings.cs | 50 +- .../src/System/Xml/Core/XmlSpace.cs | 1 + .../src/System/Xml/Core/XmlSubtreeReader.cs | 98 ++-- .../src/System/Xml/Core/XmlSubtreeReaderAsync.cs | 5 + .../src/System/Xml/Core/XmlTextReader.cs | 21 +- .../src/System/Xml/Core/XmlTextReaderImpl.cs | 534 +++++++++++++++------ .../System/Xml/Core/XmlTextReaderImplHelpers.cs | 85 ++-- .../src/System/Xml/Core/XmlWriter.cs | 39 +- .../src/System/Xml/Core/XmlWriterAsync.cs | 15 +- .../src/System/Xml/IXmlLineInfo.cs | 3 +- .../src/System/Xml/IXmlNamespaceResolver.cs | 5 +- .../System.Private.Xml/src/System/Xml/NameTable.cs | 15 +- .../src/System/Xml/XmlDownloadManager.cs | 3 +- .../src/System/Xml/XmlDownloadManagerAsync.cs | 5 +- .../src/System/Xml/XmlException.cs | 87 ++-- .../src/System/Xml/XmlNameTable.cs | 5 +- .../src/System/Xml/XmlNamespacemanager.cs | 55 ++- .../src/System/Xml/XmlResolver.cs | 17 +- .../src/System/Xml/XmlUrlResolver.cs | 15 +- .../src/System/Xml/XmlUrlResolverAsync.cs | 3 +- 41 files changed, 906 insertions(+), 468 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/Misc/HResults.cs b/src/libraries/System.Private.Xml/src/Misc/HResults.cs index 8432621..2208da6 100644 --- a/src/libraries/System.Private.Xml/src/Misc/HResults.cs +++ b/src/libraries/System.Private.Xml/src/Misc/HResults.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 /* These HRESULTs are used for mapping managed exceptions to COM error codes and vice versa through COM Interop. For background on COM error codes see diff --git a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/BinXmlToken.cs b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/BinXmlToken.cs index a6a2f96..ebfd45d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/BinXmlToken.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/BinXmlToken.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.IO; @@ -81,4 +82,4 @@ namespace System.Xml XSD_UNSIGNEDLONG = 0x8B, XSD_QNAME = 0x8C, } -} \ No newline at end of file +} diff --git a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs index cd38dc9..b0542a0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.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.IO; @@ -46,7 +47,7 @@ namespace System.Xml 11 => 2, 15 => 3, 19 => 4, - _ => throw new XmlException(SR.XmlBinary_InvalidSqlDecimal, (string[])null), + _ => throw new XmlException(SR.XmlBinary_InvalidSqlDecimal, (string[]?)null), }; m_bPrec = data[offset + 1]; m_bScale = data[offset + 2]; @@ -109,6 +110,7 @@ namespace System.Xml iulR = ulCarry; MpNormalize(rgulU, ref ciulU); } + // Normalize multi-precision number - remove leading zeroes private static void MpNormalize(uint[] rgulU, // In | Number ref int ciulU // InOut| # of digits @@ -131,6 +133,7 @@ namespace System.Xml private static ReadOnlySpan RgCLenFromPrec => new byte[] { // rely on C# compiler optimization to eliminate allocation 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; + private static byte CLenFromPrec(byte bPrec) { Debug.Assert(bPrec <= s_maxPrecision && bPrec > 0, "bPrec <= MaxPrecision && bPrec > 0", "Invalid numeric precision"); @@ -146,7 +149,7 @@ namespace System.Xml public decimal ToDecimal() { if ((int)m_data4 != 0 || m_bScale > 28) - throw new XmlException(SR.SqlTypes_ArithOverflow, (string)null); + throw new XmlException(SR.SqlTypes_ArithOverflow, (string?)null); return new decimal((int)m_data1, (int)m_data2, (int)m_data3, !IsPositive, m_bScale); } @@ -452,7 +455,7 @@ namespace System.Xml goto Error; return; Error: - throw new XmlException(SR.SqlTypes_ArithOverflow, (string)null); + throw new XmlException(SR.SqlTypes_ArithOverflow, (string?)null); } private static void BreakDownXsdDate(long val, out int yr, out int mnth, out int day, out bool negTimeZone, out int hr, out int min) @@ -477,7 +480,7 @@ Error: goto Error; return; Error: - throw new XmlException(SR.SqlTypes_ArithOverflow, (string)null); + throw new XmlException(SR.SqlTypes_ArithOverflow, (string?)null); } private static void BreakDownXsdTime(long val, out int hr, out int min, out int sec, out int ms) @@ -495,7 +498,7 @@ Error: goto Error; return; Error: - throw new XmlException(SR.SqlTypes_ArithOverflow, (string)null); + throw new XmlException(SR.SqlTypes_ArithOverflow, (string?)null); } public static string XsdDateTimeToString(long val) @@ -765,7 +768,7 @@ Error: } else { - throw new XmlException(SR.SqlTypes_ArithOverflow, (string)null); + throw new XmlException(SR.SqlTypes_ArithOverflow, (string?)null); } return timeTicks * KatmaiTimeScaleMultiplicator[scale]; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs index 655ae56..8b88ed5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.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; @@ -18,7 +19,7 @@ namespace System.Xml internal static readonly Type TypeOfObject = typeof(object); internal static readonly Type TypeOfString = typeof(string); - private static volatile Type[] s_tokenTypeMap = null; + private static volatile Type?[]? s_tokenTypeMap; private static ReadOnlySpan XsdKatmaiTimeScaleToValueLengthMap => new byte[8] { // rely on C# compiler optimization to eliminate allocation // length scale @@ -82,6 +83,7 @@ namespace System.Xml { return lname == this.localname && nsUri == this.namespaceUri; } + public bool MatchPrefix(string prefix, string lname) { return lname == this.localname && prefix == this.prefix; @@ -104,7 +106,7 @@ namespace System.Xml } - public override bool Equals(object other) + public override bool Equals(object? other) { if (other is QName) { @@ -138,10 +140,10 @@ namespace System.Xml private struct ElemInfo { public QName name; - public string xmlLang; + public string? xmlLang; public XmlSpace xmlSpace; public bool xmlspacePreserve; - public NamespaceDecl nsdecls; + public NamespaceDecl? nsdecls; public void Set(QName name, bool xmlspacePreserve) { @@ -150,9 +152,9 @@ namespace System.Xml this.xmlSpace = XmlSpace.None; this.xmlspacePreserve = xmlspacePreserve; } - public NamespaceDecl Clear() + public NamespaceDecl? Clear() { - NamespaceDecl nsdecls = this.nsdecls; + NamespaceDecl? nsdecls = this.nsdecls; this.nsdecls = null; return nsdecls; } @@ -161,7 +163,7 @@ namespace System.Xml private struct AttrInfo { public QName name; - public string val; + public string? val; public int contentPos; public int hashCode; public int prevHash; @@ -174,6 +176,7 @@ namespace System.Xml this.hashCode = 0; this.prevHash = 0; } + public void Set(QName n, int pos) { this.name = n; @@ -217,13 +220,13 @@ namespace System.Xml { public string prefix; public string uri; - public NamespaceDecl scopeLink; - public NamespaceDecl prevLink; + public NamespaceDecl? scopeLink; + public NamespaceDecl? prevLink; public int scope; public bool implied; public NamespaceDecl(string prefix, string nsuri, - NamespaceDecl nextInScope, NamespaceDecl prevDecl, + NamespaceDecl? nextInScope, NamespaceDecl? prevDecl, int scope, bool implied) { this.prefix = prefix; @@ -251,12 +254,13 @@ namespace System.Xml this.qnameCount = 1; } } + private class NestedBinXml { public SymbolTables symbolTables; public int docState; - public NestedBinXml next; - public NestedBinXml(SymbolTables symbolTables, int docState, NestedBinXml next) + public NestedBinXml? next; + public NestedBinXml(SymbolTables symbolTables, int docState, NestedBinXml? next) { this.symbolTables = symbolTables; this.docState = docState; @@ -315,14 +319,14 @@ namespace System.Xml private bool _hasTypedValue; private System.Type _valueType; // if it is a simple string value, we cache it - private string _stringValue; + private string? _stringValue; // hashtable of current namespaces private readonly Dictionary _namespaces; //Hashtable namespaces; // linked list of pushed nametables (to support nested binary-xml documents) - private NestedBinXml _prevNameInfo; + private NestedBinXml? _prevNameInfo; // XmlTextReader to handle embeded text blocks - private XmlReader _textXmlReader; + private XmlReader? _textXmlReader; // close input flag private readonly bool _closeInput; @@ -338,12 +342,12 @@ namespace System.Xml // current version of the protocol private byte _version; - public XmlSqlBinaryReader(System.IO.Stream stream, byte[] data, int len, string baseUri, bool closeInput, XmlReaderSettings settings) + public XmlSqlBinaryReader(Stream stream, byte[] data, int len, string baseUri, bool closeInput, XmlReaderSettings settings) { _unicode = System.Text.Encoding.Unicode; _xmlCharType = XmlCharType.Instance; - _xnt = settings.NameTable; + _xnt = settings.NameTable!; if (_xnt == null) { _xnt = new NameTable(); @@ -408,8 +412,7 @@ namespace System.Xml _ignorePIs = settings.IgnoreProcessingInstructions; _ignoreComments = settings.IgnoreComments; - if (s_tokenTypeMap == null) - GenerateTokenTypeMap(); + s_tokenTypeMap = s_tokenTypeMap ?? GenerateTokenTypeMap(); } public override XmlReaderSettings Settings @@ -477,7 +480,10 @@ namespace System.Xml get { if (ScanState.XmlText == _state) + { + Debug.Assert(_textXmlReader != null); return _textXmlReader.HasValue; + } else return XmlReader.HasValueInternal(_nodetype); } @@ -513,7 +519,10 @@ namespace System.Xml break; case ScanState.XmlText: - return _textXmlReader.Value; + { + Debug.Assert(_textXmlReader != null); + return _textXmlReader.Value; + } case ScanState.Attr: case ScanState.AttrValPseudoValue: @@ -540,6 +549,7 @@ namespace System.Xml break; case ScanState.XmlText: + Debug.Assert(_textXmlReader != null); adj = _textXmlReader.Depth; break; @@ -599,6 +609,7 @@ namespace System.Xml } else { + Debug.Assert(_textXmlReader != null); return _textXmlReader.XmlSpace; } } @@ -612,7 +623,7 @@ namespace System.Xml { for (int i = _elemDepth; i >= 0; i--) { - string xl = _elementStack[i].xmlLang; + string? xl = _elementStack[i].xmlLang; if (null != xl) return xl; } @@ -620,6 +631,7 @@ namespace System.Xml } else { + Debug.Assert(_textXmlReader != null); return _textXmlReader.XmlLang; } } @@ -649,17 +661,21 @@ namespace System.Xml case ScanState.AttrValPseudoValue: return _attrCount; case ScanState.XmlText: - return _textXmlReader.AttributeCount; + { + Debug.Assert(_textXmlReader != null); + return _textXmlReader.AttributeCount; + } default: return 0; } } } - public override string GetAttribute(string name, string ns) + public override string? GetAttribute(string name, string ns) { if (ScanState.XmlText == _state) { + Debug.Assert(_textXmlReader != null); return _textXmlReader.GetAttribute(name, ns); } else @@ -675,10 +691,11 @@ namespace System.Xml } } - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { if (ScanState.XmlText == _state) { + Debug.Assert(_textXmlReader != null); return _textXmlReader.GetAttribute(name); } else @@ -694,6 +711,7 @@ namespace System.Xml { if (ScanState.XmlText == _state) { + Debug.Assert(_textXmlReader != null); return _textXmlReader.GetAttribute(i); } else @@ -708,6 +726,7 @@ namespace System.Xml { if (ScanState.XmlText == _state) { + Debug.Assert(_textXmlReader != null); return UpdateFromTextReader(_textXmlReader.MoveToAttribute(name, ns)); } else @@ -730,6 +749,7 @@ namespace System.Xml { if (ScanState.XmlText == _state) { + Debug.Assert(_textXmlReader != null); return UpdateFromTextReader(_textXmlReader.MoveToAttribute(name)); } else @@ -748,6 +768,7 @@ namespace System.Xml { if (ScanState.XmlText == _state) { + Debug.Assert(_textXmlReader != null); _textXmlReader.MoveToAttribute(i); UpdateFromTextReader(true); } @@ -765,6 +786,7 @@ namespace System.Xml { if (ScanState.XmlText == _state) { + Debug.Assert(_textXmlReader != null); return UpdateFromTextReader(_textXmlReader.MoveToFirstAttribute()); } else @@ -791,6 +813,7 @@ namespace System.Xml return true; case ScanState.XmlText: + Debug.Assert(_textXmlReader != null); return UpdateFromTextReader(_textXmlReader.MoveToNextAttribute()); default: @@ -822,6 +845,7 @@ namespace System.Xml return true; case ScanState.XmlText: + Debug.Assert(_textXmlReader != null); return UpdateFromTextReader(_textXmlReader.MoveToElement()); default: @@ -870,6 +894,7 @@ namespace System.Xml return false; case ScanState.XmlText: + Debug.Assert(_textXmlReader != null); return UpdateFromTextReader(_textXmlReader.ReadAttributeValue()); default: @@ -888,9 +913,10 @@ namespace System.Xml _textXmlReader.Close(); _textXmlReader = null; } + if (null != _inStrm && _closeInput) _inStrm.Dispose(); - _inStrm = null; + _inStrm = null!; _pos = _end = 0; } @@ -902,11 +928,15 @@ namespace System.Xml } } - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { if (ScanState.XmlText == _state) + { + Debug.Assert(_textXmlReader != null); return _textXmlReader.LookupNamespace(prefix); - NamespaceDecl decl; + } + + NamespaceDecl? decl; if (prefix != null && _namespaces.TryGetValue(prefix, out decl)) { Debug.Assert(decl != null); @@ -941,10 +971,13 @@ namespace System.Xml return ReadDoc(); case ScanState.XmlText: + Debug.Assert(_textXmlReader != null); + if (_textXmlReader.Read()) { return UpdateFromTextReader(true); } + _state = ScanState.Doc; _nodetype = XmlNodeType.None; _isEmpty = false; @@ -1805,6 +1838,7 @@ namespace System.Xml { if (ScanState.XmlText == _state) { + Debug.Assert(_textXmlReader != null); IXmlNamespaceResolver resolver = (IXmlNamespaceResolver)_textXmlReader; return resolver.GetNamespacesInScope(scope); } @@ -1816,7 +1850,7 @@ namespace System.Xml // are we even inside an element? (depth==0 is where we have xml, and xmlns declared...) if (_elemDepth > 0) { - NamespaceDecl nsdecl = _elementStack[_elemDepth].nsdecls; + NamespaceDecl? nsdecl = _elementStack[_elemDepth].nsdecls; while (null != nsdecl) { nstable.Add(nsdecl.prefix, nsdecl.uri); @@ -1841,10 +1875,11 @@ namespace System.Xml } } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { if (ScanState.XmlText == _state) { + Debug.Assert(_textXmlReader != null); IXmlNamespaceResolver resolver = (IXmlNamespaceResolver)_textXmlReader; return resolver.LookupPrefix(namespaceName); } @@ -1853,16 +1888,16 @@ namespace System.Xml if (null == namespaceName) return null; - namespaceName = _xnt.Get(namespaceName); - if (null == namespaceName) + string? atomizedNamespaceName = _xnt.Get(namespaceName); + if (null == atomizedNamespaceName) return null; for (int i = _elemDepth; i >= 0; i--) { - NamespaceDecl nsdecl = _elementStack[i].nsdecls; + NamespaceDecl? nsdecl = _elementStack[i].nsdecls; while (null != nsdecl) { - if ((object)nsdecl.uri == (object)namespaceName) + if ((object)nsdecl.uri == (object?)atomizedNamespaceName) return nsdecl.prefix; nsdecl = nsdecl.scopeLink; } @@ -1951,7 +1986,7 @@ namespace System.Xml qnametable[qnameNum].Set(prefixStr, lnameStr, nsUriStr); return; BadDecl: - throw new XmlException(SR.Xml_BadNamespaceDecl, (string[])null); + throw new XmlException(SR.Xml_BadNamespaceDecl, (string[]?)null); } private void NameFlush() @@ -2319,7 +2354,7 @@ namespace System.Xml { Debug.Assert(pos >= 0 && cch >= 0); if (checked(pos + (cch * 2)) > _end) - throw new XmlException(SR.Xml_UnexpectedEOF1, (string[])null); + throw new XmlException(SR.Xml_UnexpectedEOF1, (string[]?)null); if (cch == 0) return string.Empty; // GetStringUnaligned is _significantly_ faster than unicode.GetString() @@ -2344,7 +2379,7 @@ namespace System.Xml private string GetAttributeText(int i) { - string val = _attributes[i].val; + string? val = _attributes[i].val; if (null != val) return val; @@ -2440,7 +2475,7 @@ namespace System.Xml if (prefix == "xml") return; int elemDepth = _elemDepth; - NamespaceDecl curDecl; + NamespaceDecl? curDecl; _namespaces.TryGetValue(prefix, out curDecl); if (null != curDecl) { @@ -2474,16 +2509,16 @@ namespace System.Xml _namespaces[prefix] = decl; } - private void PopNamespaces(NamespaceDecl firstInScopeChain) + private void PopNamespaces(NamespaceDecl? firstInScopeChain) { - NamespaceDecl decl = firstInScopeChain; + NamespaceDecl? decl = firstInScopeChain; while (null != decl) { if (null == decl.prevLink) _namespaces.Remove(decl.prefix); else _namespaces[decl.prefix] = decl.prevLink; - NamespaceDecl next = decl.scopeLink; + NamespaceDecl? next = decl.scopeLink; // unlink chains for better gc behaviour decl.prevLink = null; decl.scopeLink = null; @@ -2494,7 +2529,7 @@ namespace System.Xml private void GenerateImpliedXmlnsAttrs() { QName name; - NamespaceDecl decl = _elementStack[_elemDepth].nsdecls; + NamespaceDecl? decl = _elementStack[_elemDepth].nsdecls; while (null != decl) { if (decl.implied) @@ -2514,7 +2549,7 @@ namespace System.Xml private bool ReadInit(bool skipXmlDecl) { - string err = null; + string? err = null; if (!_sniffed) { // check magic header @@ -2582,7 +2617,7 @@ namespace System.Xml Error: _state = ScanState.Error; - throw new XmlException(err, (string[])null); + throw new XmlException(err, (string[]?)null); } private void ScanAttributes() @@ -2592,7 +2627,7 @@ namespace System.Xml int xmllang = -1; _mark = _pos; - string curDeclPrefix = null; + string? curDeclPrefix = null; bool lastWasValue = false; while (BinXmlToken.EndAttrs != (token = NextToken())) @@ -2655,12 +2690,14 @@ namespace System.Xml // if char checking is on, we need to scan text values to // validate that they don't use invalid CharData, so we // might as well store the saved string for quick attr value access - string val = _stringValue; + string? val = _stringValue; + if (null != val) { _attributes[_attrCount - 1].val = val; _stringValue = null; } + // namespace decls can only have text values, and should only // have a single value, so we just grab it here... if (null != curDeclPrefix) @@ -2669,6 +2706,7 @@ namespace System.Xml PushNamespace(curDeclPrefix, nsuri, false); curDeclPrefix = null; } + lastWasValue = true; } } @@ -2734,6 +2772,7 @@ namespace System.Xml next = _attributes[next].prevHash; } } + Array.Clear(_attrHashTbl, 0, tblSize); } @@ -2757,7 +2796,7 @@ namespace System.Xml Debug.Assert(_stringValue == null, "this.stringValue == null"); Debug.Assert(_token == BinXmlToken.CData, "this.token == BinXmlToken.CData"); string value = GetString(_tokDataPos, _tokLen); - StringBuilder sb = null; + StringBuilder? sb = null; while (PeekToken() == BinXmlToken.CData) { _pos++; // skip over token byte @@ -2799,7 +2838,7 @@ namespace System.Xml private void FinishEndElement() { - NamespaceDecl nsdecls = _elementStack[_elemDepth].Clear(); + NamespaceDecl? nsdecls = _elementStack[_elemDepth].Clear(); this.PopNamespaces(nsdecls); _elemDepth--; } @@ -2841,7 +2880,7 @@ namespace System.Xml { case BinXmlToken.EOF: if (_elemDepth > 0) - throw new XmlException(SR.Xml_UnexpectedEOF1, (string[])null); + throw new XmlException(SR.Xml_UnexpectedEOF1, (string[]?)null); _state = ScanState.EOF; return false; @@ -3185,6 +3224,7 @@ namespace System.Xml private void ImplReadEndNest() { + Debug.Assert(_prevNameInfo != null); NestedBinXml nested = _prevNameInfo; _symbolTables = nested.symbolTables; _docState = nested.docState; @@ -3201,9 +3241,9 @@ namespace System.Xml if (decl.scope > 0) { #if DEBUG - if ((object)decl.prefix != (object)this._xnt.Get(decl.prefix)) + if ((object)decl.prefix != (object?)this._xnt.Get(decl.prefix)) throw new Exception("Prefix not interned: \'" + decl.prefix + "\'"); - if ((object)decl.uri != (object)this._xnt.Get(decl.uri)) + if ((object)decl.uri != (object?)this._xnt.Get(decl.uri)) throw new Exception("Uri not interned: \'" + decl.uri + "\'"); #endif xnm.AddNamespace(decl.prefix, decl.uri); @@ -3236,6 +3276,7 @@ namespace System.Xml private void UpdateFromTextReader() { + Debug.Assert(_textXmlReader != null); XmlReader r = _textXmlReader; _nodetype = r.NodeType; _qnameOther.prefix = r.Prefix; @@ -3267,9 +3308,9 @@ namespace System.Xml } } - private void GenerateTokenTypeMap() + private Type?[] GenerateTokenTypeMap() { - Type[] map = new Type[256]; + Type?[] map = new Type[256]; map[(int)BinXmlToken.XSD_BOOLEAN] = typeof(bool); map[(int)BinXmlToken.SQL_TINYINT] = typeof(byte); map[(int)BinXmlToken.XSD_BYTE] = typeof(sbyte); @@ -3317,15 +3358,17 @@ namespace System.Xml map[(int)BinXmlToken.SQL_NVARCHAR] = TypeOfString; map[(int)BinXmlToken.SQL_NTEXT] = TypeOfString; map[(int)BinXmlToken.SQL_UUID] = TypeOfString; - if (s_tokenTypeMap == null) - s_tokenTypeMap = map; + return map; } private System.Type GetValueType(BinXmlToken token) { - Type t = s_tokenTypeMap[(int)token]; + Debug.Assert(s_tokenTypeMap != null); + Type? t = s_tokenTypeMap[(int)token]; + if (t == null) throw ThrowUnexpectedToken(token); + return t; } @@ -3611,7 +3654,7 @@ namespace System.Xml { if (scale > 7) { - throw new XmlException(SR.SqlTypes_ArithOverflow, (string)null); + throw new XmlException(SR.SqlTypes_ArithOverflow, (string?)null); } return XsdKatmaiTimeScaleToValueLengthMap[scale]; } @@ -4463,7 +4506,7 @@ namespace System.Xml private Exception ThrowXmlException(string res) { _state = ScanState.Error; - return new XmlException(res, (string[])null); + return new XmlException(res, (string[]?)null); } private Exception ThrowXmlException(string res, string arg1, string arg2) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/CharEntityEncoderFallback.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/CharEntityEncoderFallback.cs index aedab7e..5e5f922 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/CharEntityEncoderFallback.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/CharEntityEncoderFallback.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.Text; using System.Diagnostics; using System.Globalization; @@ -13,9 +14,9 @@ namespace System.Xml // internal class CharEntityEncoderFallback : EncoderFallback { - private CharEntityEncoderFallbackBuffer _fallbackBuffer; + private CharEntityEncoderFallbackBuffer? _fallbackBuffer; - private int[] _textContentMarks; + private int[]? _textContentMarks; private int _endMarkPos; private int _curMarkPos; private int _startOffset; @@ -62,6 +63,8 @@ namespace System.Xml internal bool CanReplaceAt(int index) { + Debug.Assert(_textContentMarks != null); + int mPos = _curMarkPos; int charPos = _startOffset + index; while (mPos < _endMarkPos && charPos >= _textContentMarks[mPos + 1]) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/ConformanceLevel.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/ConformanceLevel.cs index 73d2f6f..26902e0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/ConformanceLevel.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/ConformanceLevel.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 { public enum ConformanceLevel diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/DtdProcessing.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/DtdProcessing.cs index 1ebbd2c..47b85d7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/DtdProcessing.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/DtdProcessing.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 { // DtdProcessing enumerations specifies how will an XmlReader handle DTDs in the XML document. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/EntityHandling.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/EntityHandling.cs index f46c19d..70b893f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/EntityHandling.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/EntityHandling.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 { // Specifies how entities are handled in XmlTextReader and XmlValidatingReader. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlTernaryTree.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlTernaryTree.cs index 10dadaf..109687f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlTernaryTree.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlTernaryTree.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 // This file is generated by TernaryTreeGenerator.cs, // and is used by the TernaryTreeRO class. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdInfo.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdInfo.cs index 21e3451..2eb8905 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdInfo.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdInfo.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.Generic; @@ -45,7 +46,7 @@ namespace System.Xml /// The prefix of the attribute list to look for /// The local name of the attribute list to look for /// Interface representing an attribute list or null if none was found. - IDtdAttributeListInfo LookupAttributeList(string prefix, string localName); + IDtdAttributeListInfo? LookupAttributeList(string prefix, string localName); /// /// Returns an enumerator of all attribute lists defined in the DTD. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParser.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParser.cs index 29cb220..062f9e8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParser.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParser.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; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAdapter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAdapter.cs index 634f939..0d9075f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAdapter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAdapter.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.Text; using System.Xml.Schema; @@ -11,11 +12,11 @@ namespace System.Xml internal partial interface IDtdParserAdapter { XmlNameTable NameTable { get; } - IXmlNamespaceResolver NamespaceResolver { get; } + IXmlNamespaceResolver? NamespaceResolver { get; } - Uri BaseUri { get; } + Uri? BaseUri { get; } - char[] ParsingBuffer { get; } + char[]? ParsingBuffer { get; } int ParsingBufferLength { get; } int CurrentPosition { get; set; } int LineNo { get; } @@ -35,7 +36,7 @@ namespace System.Xml bool PushEntity(IDtdEntityInfo entity, out int entityId); - bool PopEntity(out IDtdEntityInfo oldEntity, out int newEntityId); + bool PopEntity(out IDtdEntityInfo? oldEntity, out int newEntityId); bool PushExternalSubset(string systemId, string publicId); @@ -49,7 +50,7 @@ namespace System.Xml internal interface IDtdParserAdapterWithValidation : IDtdParserAdapter { bool DtdValidation { get; } - IValidationEventHandling ValidationEventHandling { get; } + IValidationEventHandling? ValidationEventHandling { get; } } internal interface IDtdParserAdapterV1 : IDtdParserAdapterWithValidation diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAdapterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAdapterAsync.cs index 69ab5f3..fbe5652 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAdapterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAdapterAsync.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.Text; using System.Xml.Schema; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAsync.cs index 929a69f..e9acace 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IDtdParserAsync.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; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/NewLineHandling.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/NewLineHandling.cs index eb38768..9ab4aeb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/NewLineHandling.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/NewLineHandling.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 { // NewLineHandling specifies what will XmlWriter do with new line characters. The options are: diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/ReadState.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/ReadState.cs index debd969..b70702a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/ReadState.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/ReadState.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 { // Specifies the state of the XmlReader. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/ValidationType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/ValidationType.cs index b3d10f3..a5c9f0f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/ValidationType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/ValidationType.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 { // Specifies the type of validation to perform in XmlValidatingReader or in XmlReaderSettings. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/WhitespaceHandling.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/WhitespaceHandling.cs index fb26691..650cbf2 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/WhitespaceHandling.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/WhitespaceHandling.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 { // Specifies how whitespace is handled in XmlTextReader. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlParserContext.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlParserContext.cs index e6a6dd5..ae52748 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlParserContext.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlParserContext.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.Xml; using System.Text; using System; @@ -11,8 +12,8 @@ namespace System.Xml // Specifies the context that the XmLReader will use for xml fragment public class XmlParserContext { - private XmlNameTable _nt = null; - private XmlNamespaceManager _nsMgr = null; + private XmlNameTable? _nt = null; + private XmlNamespaceManager? _nsMgr = null; private string _docTypeName = string.Empty; private string _pubId = string.Empty; private string _sysId = string.Empty; @@ -20,7 +21,7 @@ namespace System.Xml private string _xmlLang = string.Empty; private XmlSpace _xmlSpace; private string _baseURI = string.Empty; - private Encoding _encoding = null; + private Encoding? _encoding = null; public XmlParserContext(XmlNameTable nt, XmlNamespaceManager nsMgr, string xmlLang, XmlSpace xmlSpace) : this(nt, nsMgr, null, null, null, null, string.Empty, xmlLang, xmlSpace) @@ -34,17 +35,17 @@ namespace System.Xml // Intentionally Empty } - public XmlParserContext(XmlNameTable nt, XmlNamespaceManager nsMgr, string docTypeName, - string pubId, string sysId, string internalSubset, string baseURI, + public XmlParserContext(XmlNameTable nt, XmlNamespaceManager nsMgr, string? docTypeName, + string? pubId, string? sysId, string? internalSubset, string baseURI, string xmlLang, XmlSpace xmlSpace) : this(nt, nsMgr, docTypeName, pubId, sysId, internalSubset, baseURI, xmlLang, xmlSpace, null) { // Intentionally Empty } - public XmlParserContext(XmlNameTable nt, XmlNamespaceManager nsMgr, string docTypeName, - string pubId, string sysId, string internalSubset, string baseURI, - string xmlLang, XmlSpace xmlSpace, Encoding enc) + public XmlParserContext(XmlNameTable nt, XmlNamespaceManager? nsMgr, string? docTypeName, + string? pubId, string? sysId, string? internalSubset, string baseURI, + string xmlLang, XmlSpace xmlSpace, Encoding? enc) { if (nsMgr != null) { @@ -54,7 +55,7 @@ namespace System.Xml } else { - if ((object)nt != (object)nsMgr.NameTable) + if ((object)nt != (object?)nsMgr.NameTable) { throw new XmlException(SR.Xml_NotSameNametable, string.Empty); } @@ -77,7 +78,7 @@ namespace System.Xml _encoding = enc; } - public XmlNameTable NameTable + public XmlNameTable? NameTable { get { @@ -89,7 +90,7 @@ namespace System.Xml } } - public XmlNamespaceManager NamespaceManager + public XmlNamespaceManager? NamespaceManager { get { @@ -185,7 +186,7 @@ namespace System.Xml } } - public Encoding Encoding + public Encoding? Encoding { get { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs index 8809d5f..9ab5aef 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.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.Diagnostics; using System.Globalization; @@ -88,7 +89,7 @@ namespace System.Xml internal const int AsyncBufferSize = 64 * 1024; //64KB // Settings - public virtual XmlReaderSettings Settings + public virtual XmlReaderSettings? Settings { get { @@ -141,7 +142,7 @@ namespace System.Xml public abstract int Depth { get; } // Gets the base URI of the current node. - public abstract string BaseURI { get; } + public abstract string? BaseURI { get; } // Gets a value indicating whether the current node is an empty element (for example, ). public abstract bool IsEmptyElement { get; } @@ -184,7 +185,7 @@ namespace System.Xml } // returns the schema info interface of the reader - public virtual IXmlSchemaInfo SchemaInfo + public virtual IXmlSchemaInfo? SchemaInfo { get { @@ -220,6 +221,7 @@ namespace System.Xml { throw CreateReadContentAsException(nameof(ReadContentAsBoolean)); } + try { return XmlConvert.ToBoolean(InternalReadContentAsString()); @@ -238,6 +240,7 @@ namespace System.Xml { throw CreateReadContentAsException(nameof(ReadContentAsDateTime)); } + try { return XmlConvert.ToDateTime(InternalReadContentAsString(), XmlDateTimeSerializationMode.RoundtripKind); @@ -256,6 +259,7 @@ namespace System.Xml { throw CreateReadContentAsException(nameof(ReadContentAsDateTimeOffset)); } + try { return XmlConvert.ToDateTimeOffset(InternalReadContentAsString()); @@ -274,6 +278,7 @@ namespace System.Xml { throw CreateReadContentAsException(nameof(ReadContentAsDouble)); } + try { return XmlConvert.ToDouble(InternalReadContentAsString()); @@ -292,6 +297,7 @@ namespace System.Xml { throw CreateReadContentAsException(nameof(ReadContentAsFloat)); } + try { return XmlConvert.ToSingle(InternalReadContentAsString()); @@ -310,6 +316,7 @@ namespace System.Xml { throw CreateReadContentAsException(nameof(ReadContentAsDecimal)); } + try { return XmlConvert.ToDecimal(InternalReadContentAsString()); @@ -328,6 +335,7 @@ namespace System.Xml { throw CreateReadContentAsException(nameof(ReadContentAsInt)); } + try { return XmlConvert.ToInt32(InternalReadContentAsString()); @@ -346,6 +354,7 @@ namespace System.Xml { throw CreateReadContentAsException(nameof(ReadContentAsLong)); } + try { return XmlConvert.ToInt64(InternalReadContentAsString()); @@ -364,6 +373,7 @@ namespace System.Xml { throw CreateReadContentAsException(nameof(ReadContentAsString)); } + return InternalReadContentAsString(); } @@ -407,6 +417,7 @@ namespace System.Xml FinishReadElementContentAsXxx(); return value; } + return string.Empty; } @@ -426,6 +437,7 @@ namespace System.Xml FinishReadElementContentAsXxx(); return value; } + return XmlConvert.ToBoolean(string.Empty); } @@ -445,6 +457,7 @@ namespace System.Xml FinishReadElementContentAsXxx(); return value; } + return XmlConvert.ToDateTime(string.Empty, XmlDateTimeSerializationMode.RoundtripKind); } @@ -465,6 +478,7 @@ namespace System.Xml FinishReadElementContentAsXxx(); return value; } + return XmlConvert.ToDouble(string.Empty); } @@ -485,6 +499,7 @@ namespace System.Xml FinishReadElementContentAsXxx(); return value; } + return XmlConvert.ToSingle(string.Empty); } @@ -565,6 +580,7 @@ namespace System.Xml FinishReadElementContentAsXxx(); return value; } + return string.Empty; } @@ -585,6 +601,7 @@ namespace System.Xml FinishReadElementContentAsXxx(); return value; } + return (returnType == typeof(string)) ? string.Empty : XmlUntypedStringConverter.Instance.FromString(string.Empty, returnType, namespaceResolver); } @@ -601,10 +618,10 @@ namespace System.Xml public abstract int AttributeCount { get; } // Gets the value of the attribute with the specified Name - public abstract string GetAttribute(string name); + public abstract string? GetAttribute(string name); // Gets the value of the attribute with the LocalName and NamespaceURI - public abstract string GetAttribute(string name, string namespaceURI); + public abstract string? GetAttribute(string name, string namespaceURI); // Gets the value of the attribute with the specified index. public abstract string GetAttribute(int i); @@ -619,7 +636,7 @@ namespace System.Xml } // Gets the value of the attribute with the specified Name. - public virtual string this[string name] + public virtual string? this[string name] { get { @@ -628,7 +645,7 @@ namespace System.Xml } // Gets the value of the attribute with the LocalName and NamespaceURI - public virtual string this[string name, string namespaceURI] + public virtual string? this[string name, string namespaceURI] { get { @@ -700,7 +717,7 @@ namespace System.Xml public abstract XmlNameTable NameTable { get; } // Resolves a namespace prefix in the current element's scope. - public abstract string LookupNamespace(string prefix); + public abstract string? LookupNamespace(string prefix); // Returns true if the XmlReader can expand general entities. public virtual bool CanResolveEntity @@ -1365,7 +1382,7 @@ namespace System.Xml private void SetNamespacesFlag(XmlTextWriter xtw) { - XmlTextReader tr = this as XmlTextReader; + XmlTextReader? tr = this as XmlTextReader; if (tr != null) { xtw.Namespaces = tr.Namespaces; @@ -1373,7 +1390,7 @@ namespace System.Xml else { #pragma warning disable 618 - XmlValidatingReader vr = this as XmlValidatingReader; + XmlValidatingReader? vr = this as XmlValidatingReader; if (vr != null) { xtw.Namespaces = vr.Namespaces; @@ -1389,6 +1406,7 @@ namespace System.Xml { throw new InvalidOperationException(SR.Xml_ReadSubtreeNotOnElement); } + return new XmlSubtreeReader(this); } @@ -1421,7 +1439,7 @@ namespace System.Xml // Internal methods // // Validation support - internal virtual XmlNamespaceManager NamespaceManager + internal virtual XmlNamespaceManager? NamespaceManager { get { @@ -1573,17 +1591,17 @@ namespace System.Xml return CanReadContentAs(this.NodeType); } - internal static Exception CreateReadContentAsException(string methodName, XmlNodeType nodeType, IXmlLineInfo lineInfo) + internal static Exception CreateReadContentAsException(string methodName, XmlNodeType nodeType, IXmlLineInfo? lineInfo) { return new InvalidOperationException(AddLineInfo(SR.Format(SR.Xml_InvalidReadContentAs, methodName, nodeType), lineInfo)); } - internal static Exception CreateReadElementContentAsException(string methodName, XmlNodeType nodeType, IXmlLineInfo lineInfo) + internal static Exception CreateReadElementContentAsException(string methodName, XmlNodeType nodeType, IXmlLineInfo? lineInfo) { return new InvalidOperationException(AddLineInfo(SR.Format(SR.Xml_InvalidReadElementContentAs, methodName, nodeType), lineInfo)); } - private static string AddLineInfo(string message, IXmlLineInfo lineInfo) + private static string AddLineInfo(string message, IXmlLineInfo? lineInfo) { if (lineInfo != null) { @@ -1598,7 +1616,7 @@ namespace System.Xml internal string InternalReadContentAsString() { string value = string.Empty; - StringBuilder sb = null; + StringBuilder? sb = null; do { switch (this.NodeType) @@ -1673,6 +1691,7 @@ namespace System.Xml { throw new XmlException(SR.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo); } + return true; } @@ -1682,6 +1701,7 @@ namespace System.Xml { throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString()); } + this.Read(); } @@ -1693,16 +1713,18 @@ namespace System.Xml { return true; } - IXmlSchemaInfo schemaInfo = this.SchemaInfo; + + IXmlSchemaInfo? schemaInfo = this.SchemaInfo; if (schemaInfo != null && schemaInfo.IsDefault) { return true; } + return false; } } - internal virtual IDtdInfo DtdInfo + internal virtual IDtdInfo? DtdInfo { get { @@ -1712,32 +1734,37 @@ namespace System.Xml internal static ConformanceLevel GetV1ConformanceLevel(XmlReader reader) { - XmlTextReaderImpl tri = GetXmlTextReaderImpl(reader); + XmlTextReaderImpl? tri = GetXmlTextReaderImpl(reader); return tri != null ? tri.V1ComformanceLevel : ConformanceLevel.Document; } - private static XmlTextReaderImpl GetXmlTextReaderImpl(XmlReader reader) + private static XmlTextReaderImpl? GetXmlTextReaderImpl(XmlReader reader) { - XmlTextReaderImpl tri = reader as XmlTextReaderImpl; + XmlTextReaderImpl? tri = reader as XmlTextReaderImpl; + if (tri != null) { return tri; } - XmlTextReader tr = reader as XmlTextReader; + XmlTextReader? tr = reader as XmlTextReader; + if (tr != null) { return tr.Impl; } - XmlValidatingReaderImpl vri = reader as XmlValidatingReaderImpl; + XmlValidatingReaderImpl? vri = reader as XmlValidatingReaderImpl; + if (vri != null) { return vri.ReaderImpl; } + #pragma warning disable 618 - XmlValidatingReader vr = reader as XmlValidatingReader; + XmlValidatingReader? vr = reader as XmlValidatingReader; #pragma warning restore 618 + if (vr != null) { return vr.Impl.ReaderImpl; @@ -1770,11 +1797,11 @@ namespace System.Xml // Creates an XmlReader according to the settings for parsing XML from the given Uri. public static XmlReader Create(string inputUri, XmlReaderSettings settings) { - return XmlReader.Create(inputUri, settings, (XmlParserContext)null); + return XmlReader.Create(inputUri, settings, (XmlParserContext?)null); } // Creates an XmlReader according to the settings and parser context for parsing XML from the given Uri. - public static XmlReader Create(string inputUri, XmlReaderSettings settings, XmlParserContext inputContext) + public static XmlReader Create(string inputUri, XmlReaderSettings settings, XmlParserContext? inputContext) { settings ??= XmlReaderSettings.s_defaultReaderSettings; return settings.CreateReader(inputUri, inputContext); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderAsync.cs index 098d367..ceefc44 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderAsync.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.Security; @@ -340,7 +341,7 @@ namespace System.Xml internal async Task InternalReadContentAsStringAsync() { string value = string.Empty; - StringBuilder sb = null; + StringBuilder? sb = null; do { switch (this.NodeType) 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 e74adf0..d4eb05c 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 @@ -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.Diagnostics; using System.Globalization; @@ -23,10 +24,10 @@ namespace System.Xml // Nametable - private XmlNameTable _nameTable; + private XmlNameTable? _nameTable; // XmlResolver - private XmlResolver _xmlResolver = null; + private XmlResolver? _xmlResolver = null; // Text settings private int _lineNumberOffset; @@ -50,8 +51,8 @@ namespace System.Xml //Validation settings private ValidationType _validationType; private XmlSchemaValidationFlags _validationFlags; - private XmlSchemaSet _schemas; - private ValidationEventHandler _valEventHandler; + private XmlSchemaSet? _schemas; + private ValidationEventHandler? _valEventHandler; // other settings private bool _closeInput; @@ -62,8 +63,8 @@ namespace System.Xml // Creation of validating readers is hidden behind a delegate which is only initialized if the ValidationType // property is set. This is for AOT builds where the tree shaker can reduce the validating readers away // if nobody calls the ValidationType setter. Might also help with non-AOT build when ILLinker is used. - private delegate XmlReader AddValidationFunc(XmlReader reader, XmlResolver resolver, bool addConformanceWrapper); - private AddValidationFunc _addValidationFunc; + private delegate XmlReader AddValidationFunc(XmlReader reader, XmlResolver? resolver, bool addConformanceWrapper); + private AddValidationFunc? _addValidationFunc; // // Constructor @@ -91,7 +92,7 @@ namespace System.Xml } // Nametable - public XmlNameTable NameTable + public XmlNameTable? NameTable { get { @@ -111,7 +112,7 @@ namespace System.Xml set; // keep set internal as we need to call it from the schema validation code } - public XmlResolver XmlResolver + public XmlResolver? XmlResolver { set { @@ -121,7 +122,7 @@ namespace System.Xml } } - internal XmlResolver GetXmlResolver() + internal XmlResolver? GetXmlResolver() { return _xmlResolver; } @@ -129,7 +130,7 @@ namespace System.Xml //This is used by get XmlResolver in Xsd. //Check if the config set to prohibit default resovler //notice we must keep GetXmlResolver() to avoid dead lock when init System.Config.ConfigurationManager - internal XmlResolver GetXmlResolver_CheckConfig() + internal XmlResolver? GetXmlResolver_CheckConfig() { if (!LocalAppContextSwitches.AllowDefaultResolver && !IsXmlResolverSet) return null; @@ -401,7 +402,7 @@ namespace System.Xml public XmlReaderSettings Clone() { - XmlReaderSettings clonedSettings = this.MemberwiseClone() as XmlReaderSettings; + XmlReaderSettings clonedSettings = (this.MemberwiseClone() as XmlReaderSettings)!; clonedSettings.ReadOnly = false; return clonedSettings; } @@ -409,12 +410,12 @@ namespace System.Xml // // Internal methods // - internal ValidationEventHandler GetEventHandler() + internal ValidationEventHandler? GetEventHandler() { return _valEventHandler; } - internal XmlReader CreateReader(string inputUri, XmlParserContext inputContext) + internal XmlReader CreateReader(string inputUri, XmlParserContext? inputContext) { if (inputUri == null) { @@ -445,7 +446,7 @@ namespace System.Xml return reader; } - internal XmlReader CreateReader(Stream input, Uri baseUri, string baseUriString, XmlParserContext inputContext) + internal XmlReader CreateReader(Stream input, Uri? baseUri, string baseUriString, XmlParserContext? inputContext) { if (input == null) { @@ -480,7 +481,7 @@ namespace System.Xml return reader; } - internal XmlReader CreateReader(TextReader input, string baseUriString, XmlParserContext inputContext) + internal XmlReader CreateReader(TextReader input, string baseUriString, XmlParserContext? inputContext) { if (input == null) { @@ -545,7 +546,7 @@ namespace System.Xml Initialize(null); } - private void Initialize(XmlResolver resolver) + private void Initialize(XmlResolver? resolver) { _nameTable = null; _xmlResolver = resolver; @@ -579,7 +580,7 @@ namespace System.Xml internal XmlReader AddValidation(XmlReader reader) { - XmlResolver resolver = null; + XmlResolver? resolver = null; if (_validationType == ValidationType.Schema) { resolver = GetXmlResolver_CheckConfig(); @@ -596,7 +597,7 @@ namespace System.Xml private XmlReader AddValidationAndConformanceWrapper(XmlReader reader) { - XmlResolver resolver = null; + XmlResolver? resolver = null; if (_validationType == ValidationType.Schema) { resolver = GetXmlResolver_CheckConfig(); @@ -605,7 +606,7 @@ namespace System.Xml return AddValidationAndConformanceInternal(reader, resolver, addConformanceWrapper: true); } - private XmlReader AddValidationAndConformanceInternal(XmlReader reader, XmlResolver resolver, bool addConformanceWrapper) + private XmlReader AddValidationAndConformanceInternal(XmlReader reader, XmlResolver? resolver, bool addConformanceWrapper) { // We have to avoid calling the _addValidationFunc delegate if there's no validation to setup // since it would not be initialized (to allow AOT compilers to reduce it away). @@ -621,13 +622,14 @@ namespace System.Xml } else { + Debug.Assert(_addValidationFunc != null); reader = _addValidationFunc(reader, resolver, addConformanceWrapper); } return reader; } - private XmlReader AddValidationInternal(XmlReader reader, XmlResolver resolver, bool addConformanceWrapper) + private XmlReader AddValidationInternal(XmlReader reader, XmlResolver? resolver, bool addConformanceWrapper) { // wrap with DTD validating reader if (_validationType == ValidationType.DTD) @@ -656,7 +658,7 @@ namespace System.Xml internal XmlReader AddConformanceWrapper(XmlReader baseReader) { - XmlReaderSettings baseReaderSettings = baseReader.Settings; + XmlReaderSettings? baseReaderSettings = baseReader.Settings; bool checkChars = false; bool noWhitespace = false; bool noComments = false; @@ -674,10 +676,10 @@ namespace System.Xml } // get the V1 XmlTextReader ref - XmlTextReader v1XmlTextReader = baseReader as XmlTextReader; + XmlTextReader? v1XmlTextReader = baseReader as XmlTextReader; if (v1XmlTextReader == null) { - XmlValidatingReader vr = baseReader as XmlValidatingReader; + XmlValidatingReader? vr = baseReader as XmlValidatingReader; if (vr != null) { v1XmlTextReader = (XmlTextReader)vr.Reader; @@ -762,7 +764,7 @@ namespace System.Xml if (needWrap) { - IXmlNamespaceResolver readerAsNSResolver = baseReader as IXmlNamespaceResolver; + IXmlNamespaceResolver? readerAsNSResolver = baseReader as IXmlNamespaceResolver; if (readerAsNSResolver != null) { return new XmlCharCheckingReaderWithNS(baseReader, readerAsNSResolver, checkChars, noWhitespace, noComments, noPIs, dtdProc); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSpace.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSpace.cs index 7d6541c..c8f594b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSpace.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSpace.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 { // An enumeration for the xml:space scope used in XmlReader and XmlWriter. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReader.cs index 82876f5..8b2c129 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReader.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; using System.Diagnostics; @@ -25,8 +26,14 @@ namespace System.Xml internal string namespaceUri; internal string value; - internal NodeData() + internal NodeData(XmlNodeType nodeType, string localName, string prefix, string name, string namespaceUri, string value) { + this.type = nodeType; + this.localName = localName; + this.prefix = prefix; + this.name = name; + this.namespaceUri = namespaceUri; + this.value = value; } internal void Set(XmlNodeType nodeType, string localName, string prefix, string name, string namespaceUri, string value) @@ -66,7 +73,7 @@ namespace System.Xml // namespace management private readonly XmlNamespaceManager _nsManager; - private NodeData[] _nsAttributes; + private NodeData?[]? _nsAttributes; private int _nsAttrCount; private int _curNsAttr = -1; @@ -75,11 +82,11 @@ namespace System.Xml // incremental reading of added xmlns nodes (ReadValueChunk, ReadContentAsBase64, ReadContentAsBinHex) private int _nsIncReadOffset; - private IncrementalReadDecoder _binDecoder; + private IncrementalReadDecoder? _binDecoder; // cached nodes private bool _useCurNode; - private NodeData _curNode; + private NodeData _curNode = null!; // node used for a text node of ReadAttributeValue or as Initial or EOF node private readonly NodeData _tmpNode; @@ -99,8 +106,7 @@ namespace System.Xml _xmlns = reader.NameTable.Add("xmlns"); _xmlnsUri = reader.NameTable.Add(XmlReservedNs.NsXmlNs); - _tmpNode = new NodeData(); - _tmpNode.Set(XmlNodeType.None, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty); + _tmpNode = new NodeData(XmlNodeType.None, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty); SetCurrentNode(_tmpNode); } @@ -120,7 +126,7 @@ namespace System.Xml { get { - return (_useCurNode) ? _curNode.name : reader.Name; + return _useCurNode ? _curNode.name! : reader.Name; } } @@ -176,7 +182,7 @@ namespace System.Xml } } - public override string BaseURI + public override string? BaseURI { get { @@ -238,45 +244,51 @@ namespace System.Xml } } - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { if (!InAttributeActiveState) { return null; } - string attr = reader.GetAttribute(name); + string? attr = reader.GetAttribute(name); if (attr != null) { return attr; } + for (int i = 0; i < _nsAttrCount; i++) { - if (name == _nsAttributes[i].name) + if (name == _nsAttributes![i]!.name) { - return _nsAttributes[i].value; + // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34644 + return _nsAttributes[i]!.value; } } return null; } - public override string GetAttribute(string name, string namespaceURI) + public override string? GetAttribute(string name, string namespaceURI) { if (!InAttributeActiveState) { return null; } - string attr = reader.GetAttribute(name, namespaceURI); + + string? attr = reader.GetAttribute(name, namespaceURI); if (attr != null) { return attr; } + for (int i = 0; i < _nsAttrCount; i++) { - if (name == _nsAttributes[i].localName && namespaceURI == _xmlnsUri) + if (name == _nsAttributes![i]!.localName && namespaceURI == _xmlnsUri) { - return _nsAttributes[i].value; + // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34644 + return _nsAttributes[i]!.value; } } + return null; } @@ -293,7 +305,7 @@ namespace System.Xml } else if (i - n < _nsAttrCount) { - return _nsAttributes[i - n].value; + return _nsAttributes![i - n]!.value; } else { @@ -313,9 +325,10 @@ namespace System.Xml _useCurNode = false; return true; } + for (int i = 0; i < _nsAttrCount; i++) { - if (name == _nsAttributes[i].name) + if (name == _nsAttributes![i]!.name) { MoveToNsAttribute(i); return true; @@ -336,9 +349,10 @@ namespace System.Xml _useCurNode = false; return true; } + for (int i = 0; i < _nsAttrCount; i++) { - if (name == _nsAttributes[i].localName && ns == _xmlnsUri) + if (name == _nsAttributes![i]!.localName && ns == _xmlnsUri) { MoveToNsAttribute(i); return true; @@ -854,6 +868,8 @@ namespace System.Xml { return 0; } + + Debug.Assert(_binDecoder != null); _binDecoder.SetNextOutputBuffer(buffer, index, count); _nsIncReadOffset += _binDecoder.Decode(_curNode.value, _nsIncReadOffset, _curNode.value.Length - _nsIncReadOffset); return _binDecoder.DecodedCount; @@ -990,6 +1006,8 @@ namespace System.Xml { return 0; } + + Debug.Assert(_binDecoder != null); _binDecoder.SetNextOutputBuffer(buffer, index, count); _nsIncReadOffset += _binDecoder.Decode(_curNode.value, _nsIncReadOffset, _curNode.value.Length - _nsIncReadOffset); return _binDecoder.DecodedCount; @@ -1142,7 +1160,7 @@ namespace System.Xml } } - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { return ((IXmlNamespaceResolver)this).LookupNamespace(prefix); } @@ -1165,7 +1183,7 @@ namespace System.Xml { if (!_useCurNode) { - IXmlLineInfo lineInfo = reader as IXmlLineInfo; + IXmlLineInfo? lineInfo = reader as IXmlLineInfo; if (lineInfo != null) { return lineInfo.LineNumber; @@ -1181,7 +1199,7 @@ namespace System.Xml { if (!_useCurNode) { - IXmlLineInfo lineInfo = reader as IXmlLineInfo; + IXmlLineInfo? lineInfo = reader as IXmlLineInfo; if (lineInfo != null) { return lineInfo.LinePosition; @@ -1208,7 +1226,7 @@ namespace System.Xml return _nsManager.GetNamespacesInScope(scope); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { if (!InNamespaceActiveState) { @@ -1217,7 +1235,7 @@ namespace System.Xml return _nsManager.LookupNamespace(prefix); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { if (!InNamespaceActiveState) { @@ -1292,6 +1310,7 @@ namespace System.Xml { _nsAttributes = new NodeData[InitialNamespaceAttributeCount]; } + if (index == _nsAttributes.Length) { NodeData[] newNsAttrs = new NodeData[_nsAttributes.Length * 2]; @@ -1299,17 +1318,30 @@ namespace System.Xml _nsAttributes = newNsAttrs; } - if (_nsAttributes[index] == null) + string localName; + string attrPrefix; + string name; + + if (prefix.Length == 0) { - _nsAttributes[index] = new NodeData(); + localName = _xmlns; + attrPrefix = string.Empty; + name = _xmlns; } - if (prefix.Length == 0) + else + { + localName = prefix; + attrPrefix = _xmlns; + name = reader.NameTable.Add(string.Concat(_xmlns, ":", prefix)); + } + + if (_nsAttributes[index] == null) { - _nsAttributes[index].Set(XmlNodeType.Attribute, _xmlns, string.Empty, _xmlns, _xmlnsUri, ns); + _nsAttributes[index] = new NodeData(XmlNodeType.Attribute, localName, attrPrefix, name, _xmlnsUri, ns); } else { - _nsAttributes[index].Set(XmlNodeType.Attribute, prefix, _xmlns, reader.NameTable.Add(string.Concat(_xmlns, ":", prefix)), _xmlnsUri, ns); + _nsAttributes[index]!.Set(XmlNodeType.Attribute, localName, attrPrefix, name, _xmlnsUri, ns); } Debug.Assert(_state == State.ClearNsAttributes || _state == State.Interactive || _state == State.PopNamespaceScope); @@ -1322,13 +1354,13 @@ namespace System.Xml { for (int i = 0; i < _nsAttrCount; i++) { - if (Ref.Equal(prefix, _nsAttributes[i].prefix) && - Ref.Equal(localName, _nsAttributes[i].localName)) + if (Ref.Equal(prefix, _nsAttributes![i]!.prefix) && + Ref.Equal(localName, _nsAttributes![i]!.localName)) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34644 { if (i < _nsAttrCount - 1) { // swap - NodeData tmpNodeData = _nsAttributes[i]; + NodeData tmpNodeData = _nsAttributes![i]!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34644 _nsAttributes[i] = _nsAttributes[_nsAttrCount - 1]; _nsAttributes[_nsAttrCount - 1] = tmpNodeData; } @@ -1344,7 +1376,7 @@ namespace System.Xml reader.MoveToElement(); _curNsAttr = index; _nsIncReadOffset = 0; - SetCurrentNode(_nsAttributes[index]); + SetCurrentNode(_nsAttributes![index]!); } private bool InitReadElementContentAsBinary(State binaryState) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReaderAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReaderAsync.cs index d722745..ecbff26 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReaderAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlSubtreeReaderAsync.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; using System.Diagnostics; @@ -272,6 +273,8 @@ namespace System.Xml { return 0; } + + Debug.Assert(_binDecoder != null); _binDecoder.SetNextOutputBuffer(buffer, index, count); _nsIncReadOffset += _binDecoder.Decode(_curNode.value, _nsIncReadOffset, _curNode.value.Length - _nsIncReadOffset); return _binDecoder.DecodedCount; @@ -408,6 +411,8 @@ namespace System.Xml { return 0; } + + Debug.Assert(_binDecoder != null); _binDecoder.SetNextOutputBuffer(buffer, index, count); _nsIncReadOffset += _binDecoder.Decode(_curNode.value, _nsIncReadOffset, _curNode.value.Length - _nsIncReadOffset); return _binDecoder.DecodedCount; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReader.cs index b51c0fb..f984f0a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReader.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; @@ -149,7 +150,7 @@ namespace System.Xml get { return _impl.Depth; } } - public override string BaseURI + public override string? BaseURI { get { return _impl.BaseURI; } } @@ -183,12 +184,12 @@ namespace System.Xml public override int AttributeCount { get { return _impl.AttributeCount; } } - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { return _impl.GetAttribute(name); } - public override string GetAttribute(string localName, string namespaceURI) + public override string? GetAttribute(string localName, string namespaceURI) { return _impl.GetAttribute(localName, namespaceURI); } @@ -263,9 +264,9 @@ namespace System.Xml get { return _impl.NameTable; } } - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { - string ns = _impl.LookupNamespace(prefix); + string? ns = _impl.LookupNamespace(prefix); if (ns != null && ns.Length == 0) { ns = null; @@ -342,12 +343,12 @@ namespace System.Xml return _impl.GetNamespacesInScope(scope); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { return _impl.LookupNamespace(prefix); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { return _impl.LookupPrefix(namespaceName); } @@ -377,7 +378,7 @@ namespace System.Xml set { _impl.Normalization = value; } } - public Encoding Encoding + public Encoding? Encoding { get { return _impl.Encoding; } } @@ -444,7 +445,7 @@ namespace System.Xml get { return _impl; } } - internal override XmlNamespaceManager NamespaceManager + internal override XmlNamespaceManager? NamespaceManager { get { return _impl.NamespaceManager; } } @@ -455,7 +456,7 @@ namespace System.Xml set { _impl.XmlValidatingReaderCompatibilityMode = value; } } - internal override IDtdInfo DtdInfo + internal override IDtdInfo? DtdInfo { get { return _impl.DtdInfo; } } 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 491d76a..b2d1396 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 @@ -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,12 +12,13 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { internal partial class XmlTextReaderImpl : XmlReader, IXmlLineInfo, IXmlNamespaceResolver { - private static UTF8Encoding s_utf8BomThrowing; + private static UTF8Encoding? s_utf8BomThrowing; private static UTF8Encoding UTF8BomThrowing => s_utf8BomThrowing ?? (s_utf8BomThrowing = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true, throwOnInvalidBytes: true)); @@ -119,19 +121,19 @@ namespace System.Xml { public bool useAsync = false; - public Stream inputStream; - public byte[] inputBytes; + public Stream? inputStream; + public byte[]? inputBytes; public int inputByteCount; - public Uri inputbaseUri; - public string inputUriStr; - public XmlResolver inputUriResolver; - public XmlParserContext inputContext; - public TextReader inputTextReader; + public Uri? inputbaseUri; + public string? inputUriStr; + public XmlResolver? inputUriResolver; + public XmlParserContext? inputContext; + public TextReader? inputTextReader; public InitInputType initType = InitInputType.Invalid; } - private LaterInitParam _laterInitParam = null; + private LaterInitParam? _laterInitParam = null; private enum InitInputType { @@ -170,14 +172,14 @@ namespace System.Xml private int _attrDuplWalkCount; private bool _attrNeedNamespaceLookup; private bool _fullAttrCleanup; - private NodeData[] _attrDuplSortingArray; + private NodeData[]? _attrDuplSortingArray; // name table - private XmlNameTable _nameTable; + private XmlNameTable _nameTable = null!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/43523 private bool _nameTableFromSettings; // resolver - private XmlResolver _xmlResolver; + private XmlResolver? _xmlResolver; // this is only for constructors that takes url private readonly string _url = string.Empty; @@ -202,46 +204,46 @@ namespace System.Xml private readonly bool _v1Compat; // namespace handling - private XmlNamespaceManager _namespaceManager; + private XmlNamespaceManager? _namespaceManager; private string _lastPrefix = string.Empty; // xml context (xml:space, xml:lang, default namespace) private XmlContext _xmlContext; // stack of parsing states (=stack of entities) - private ParsingState[] _parsingStatesStack; + private ParsingState[]? _parsingStatesStack; private int _parsingStatesStackTop = -1; // current node base uri and encoding - private string _reportedBaseUri; - private Encoding _reportedEncoding; + private string? _reportedBaseUri; + private Encoding? _reportedEncoding; // DTD - private IDtdInfo _dtdInfo; + private IDtdInfo? _dtdInfo; // fragment parsing private XmlNodeType _fragmentType = XmlNodeType.Document; - private XmlParserContext _fragmentParserContext; + private XmlParserContext? _fragmentParserContext; private bool _fragment; // incremental read - private IncrementalReadDecoder _incReadDecoder; + private IncrementalReadDecoder? _incReadDecoder; private IncrementalReadState _incReadState; private LineInfo _incReadLineInfo; - private BinHexDecoder _binHexDecoder; - private Base64Decoder _base64Decoder; + private BinHexDecoder? _binHexDecoder; + private Base64Decoder? _base64Decoder; private int _incReadDepth; private int _incReadLeftStartPos; private int _incReadLeftEndPos; - private IncrementalReadCharsDecoder _readCharsDecoder; + private IncrementalReadCharsDecoder? _readCharsDecoder; // ReadAttributeValue helpers private int _attributeValueBaseEntityId; private bool _emptyEntityInAttributeResolved; // Validation helpers - private IValidationEventHandling _validationEventHandling; - private OnDefaultAttributeUseDelegate _onDefaultAttributeUse; + private IValidationEventHandling? _validationEventHandling; + private OnDefaultAttributeUseDelegate? _onDefaultAttributeUse; private bool _validatingReaderCompatFlag; @@ -253,7 +255,7 @@ namespace System.Xml private int _nextEntityId = 1; private ParsingMode _parsingMode; private ReadState _readState = ReadState.Initial; - private IDtdEntityInfo _lastEntity; + private IDtdEntityInfo? _lastEntity; private bool _afterResetState; private int _documentStartBytePos; private int _readValueOffset; @@ -263,7 +265,7 @@ namespace System.Xml private long _charactersFromEntities; // All entities that are currently being processed - private Dictionary _currentEntities; + private Dictionary? _currentEntities; // DOM helpers private bool _disableUndeclaredEntityCheck; @@ -301,8 +303,16 @@ namespace System.Xml internal XmlTextReaderImpl() { - _curNode = new NodeData(); _parsingFunction = ParsingFunction.NoData; + _outerReader = this; + _xmlContext = new XmlContext(); + _nameTable = new NameTable(); + _nodes = new NodeData[NodesInitialSize]; + _nodes[0] = new NodeData(); + _curNode = _nodes[0]; + _stringBuilder = new StringBuilder(); + _xml = _nameTable.Add("xml"); + _xmlNs = _nameTable.Add("xmlns"); } // Initializes a new instance of the XmlTextReaderImpl class with the specified XmlNameTable. @@ -348,7 +358,7 @@ namespace System.Xml } // This constructor is used when creating XmlTextReaderImpl reader via "XmlReader.Create(..)" - private XmlTextReaderImpl(XmlResolver resolver, XmlReaderSettings settings, XmlParserContext context) + private XmlTextReaderImpl(XmlResolver? resolver, XmlReaderSettings settings, XmlParserContext? context) { _useAsync = settings.Async; _v1Compat = false; @@ -357,7 +367,7 @@ namespace System.Xml _xmlContext = new XmlContext(); // create or get nametable and namespace manager from XmlParserContext - XmlNameTable nt = settings.NameTable; + XmlNameTable? nt = settings.NameTable; if (context == null) { if (nt == null) @@ -369,12 +379,14 @@ namespace System.Xml { _nameTableFromSettings = true; } + _nameTable = nt; _namespaceManager = new XmlNamespaceManager(nt); } else { SetupFromParserContext(context, settings); + Debug.Assert(_nameTable != null); nt = _nameTable; } @@ -443,16 +455,20 @@ namespace System.Xml internal XmlTextReaderImpl(Stream input) : this(string.Empty, input, new NameTable()) { } + internal XmlTextReaderImpl(Stream input, XmlNameTable nt) : this(string.Empty, input, nt) { } + internal XmlTextReaderImpl(string url, Stream input) : this(url, input, new NameTable()) { } + internal XmlTextReaderImpl(string url, Stream input, XmlNameTable nt) : this(nt) { ConvertAbsoluteUnixPathToAbsoluteUri(ref url, resolver: null); _namespaceManager = new XmlNamespaceManager(nt); + if (url == null || url.Length == 0) { InitStreamInput(input, null); @@ -461,6 +477,7 @@ namespace System.Xml { InitStreamInput(url, input, null); } + _reportedBaseUri = _ps.baseUriStr; _reportedEncoding = _ps.encoding; } @@ -470,12 +487,15 @@ namespace System.Xml internal XmlTextReaderImpl(TextReader input) : this(string.Empty, input, new NameTable()) { } + internal XmlTextReaderImpl(TextReader input, XmlNameTable nt) : this(string.Empty, input, nt) { } + internal XmlTextReaderImpl(string url, TextReader input) : this(url, input, new NameTable()) { } + internal XmlTextReaderImpl(string url, TextReader input, XmlNameTable nt) : this(nt) { ConvertAbsoluteUnixPathToAbsoluteUri(ref url, resolver: null); @@ -491,7 +511,7 @@ namespace System.Xml internal XmlTextReaderImpl(Stream xmlFragment, XmlNodeType fragType, XmlParserContext context) : this((context != null && context.NameTable != null) ? context.NameTable : new NameTable()) { - Encoding enc = (context != null) ? context.Encoding : null; + Encoding? enc = (context != null) ? context.Encoding : null; if (context == null || context.BaseURI == null || context.BaseURI.Length == 0) { InitStreamInput(xmlFragment, enc); @@ -502,6 +522,7 @@ namespace System.Xml // it is safe as this resolver will not be used to resolve DTD url's InitStreamInput(GetTempResolver().ResolveUri(null, context.BaseURI), xmlFragment, enc); } + InitFragmentReader(fragType, context, false); _reportedBaseUri = _ps.baseUriStr; @@ -527,6 +548,7 @@ namespace System.Xml _reportedBaseUri = context.BaseURI; InitStringInput(context.BaseURI, Encoding.Unicode, xmlFragment); } + InitFragmentReader(fragType, context, false); _reportedEncoding = _ps.encoding; } @@ -555,10 +577,12 @@ namespace System.Xml { throw new ArgumentNullException(nameof(url)); } + if (url.Length == 0) { throw new ArgumentException(SR.Xml_EmptyUrl, nameof(url)); } + _namespaceManager = new XmlNamespaceManager(nt); _url = url; @@ -575,7 +599,7 @@ namespace System.Xml // Initializes a new instance of the XmlTextReaderImpl class with the specified arguments. // This constructor is used when creating XmlTextReaderImpl via XmlReader.Create - internal XmlTextReaderImpl(string uriStr, XmlReaderSettings settings, XmlParserContext context, XmlResolver uriResolver) + internal XmlTextReaderImpl(string uriStr, XmlReaderSettings settings, XmlParserContext? context, XmlResolver uriResolver) : this(settings.GetXmlResolver(), settings, context) { Uri baseUri = uriResolver.ResolveUri(null, uriStr); @@ -604,6 +628,7 @@ namespace System.Xml _laterInitParam.inputContext = context; _laterInitParam.inputUriResolver = uriResolver; _laterInitParam.initType = InitInputType.UriString; + if (!settings.Async) { //if not set Async flag, finish the init in create stage. @@ -617,18 +642,22 @@ namespace System.Xml private void FinishInitUriString() { - Stream stream = null; + Stream? stream = null; + Debug.Assert(_laterInitParam != null); + Debug.Assert(_laterInitParam.inputUriResolver != null); + Debug.Assert(_laterInitParam.inputbaseUri != null); + Debug.Assert(_reportedBaseUri != null); if (_laterInitParam.useAsync) { - //this will be hit when user create a XmlReader by setting Async, but the first call is Read() instead of ReadAsync(), - //then we still should create an async stream here. And wait for the method finish. + // this will be hit when user create a XmlReader by setting Async, but the first call is Read() instead of ReadAsync(), + // then we still should create an async stream here. And wait for the method finish. Task t = _laterInitParam.inputUriResolver.GetEntityAsync(_laterInitParam.inputbaseUri, string.Empty, typeof(Stream)); stream = (Stream)t.GetAwaiter().GetResult(); } else { - stream = (Stream)_laterInitParam.inputUriResolver.GetEntity(_laterInitParam.inputbaseUri, string.Empty, typeof(Stream)); + stream = (Stream?)_laterInitParam.inputUriResolver.GetEntity(_laterInitParam.inputbaseUri, string.Empty, typeof(Stream)); } if (stream == null) @@ -636,7 +665,7 @@ namespace System.Xml throw new XmlException(SR.Xml_CannotResolveUrl, _laterInitParam.inputUriStr); } - Encoding enc = null; + Encoding? enc = null; // get Encoding from XmlParserContext if (_laterInitParam.inputContext != null) { @@ -661,16 +690,18 @@ namespace System.Xml stream.Dispose(); throw; } + _laterInitParam = null; } // Initializes a new instance of the XmlTextReaderImpl class with the specified arguments. // This constructor is used when creating XmlTextReaderImpl via XmlReader.Create - internal XmlTextReaderImpl(Stream stream, byte[] bytes, int byteCount, XmlReaderSettings settings, Uri baseUri, string baseUriStr, - XmlParserContext context, bool closeInput) + internal XmlTextReaderImpl(Stream stream, byte[]? bytes, int byteCount, XmlReaderSettings settings, Uri? baseUri, string baseUriStr, + XmlParserContext? context, bool closeInput) : this(settings.GetXmlResolver(), settings, context) { ConvertAbsoluteUnixPathToAbsoluteUri(ref baseUriStr, settings.GetXmlResolver()); + // get BaseUri from XmlParserContext if (context != null) { @@ -681,6 +712,7 @@ namespace System.Xml { Throw(SR.Xml_DoubleBaseUri); } + Debug.Assert(baseUri == null); baseUriStr = context.BaseURI; } @@ -710,7 +742,11 @@ namespace System.Xml private void FinishInitStream() { - Encoding enc = null; + Encoding? enc = null; + + Debug.Assert(_laterInitParam != null); + Debug.Assert(_laterInitParam.inputStream != null); + Debug.Assert(_reportedBaseUri != null); // get Encoding from XmlParserContext if (_laterInitParam.inputContext != null) @@ -728,12 +764,13 @@ namespace System.Xml { ProcessDtdFromParserContext(_laterInitParam.inputContext); } + _laterInitParam = null; } // Initializes a new instance of the XmlTextReaderImpl class with the specified arguments. // This constructor is used when creating XmlTextReaderImpl via XmlReader.Create - internal XmlTextReaderImpl(TextReader input, XmlReaderSettings settings, string baseUriStr, XmlParserContext context) + internal XmlTextReaderImpl(TextReader input, XmlReaderSettings settings, string baseUriStr, XmlParserContext? context) : this(settings.GetXmlResolver(), settings, context) { ConvertAbsoluteUnixPathToAbsoluteUri(ref baseUriStr, settings.GetXmlResolver()); @@ -766,6 +803,10 @@ namespace System.Xml private void FinishInitTextReader() { + Debug.Assert(_laterInitParam != null); + Debug.Assert(_laterInitParam.inputTextReader != null); + Debug.Assert(_reportedBaseUri != null); + // init ParsingState InitTextReaderInput(_reportedBaseUri, _laterInitParam.inputTextReader); @@ -813,6 +854,7 @@ namespace System.Xml case XmlNodeType.Document: settings.ConformanceLevel = ConformanceLevel.Document; break; default: Debug.Fail($"Unexpected fragment type {_fragmentType}"); goto case XmlNodeType.None; } + settings.CheckCharacters = _checkCharacters; settings.LineNumberOffset = _lineNumberOffset; settings.LinePositionOffset = _linePositionOffset; @@ -860,7 +902,7 @@ namespace System.Xml { get { - return _curNode.ns; + return _curNode.ns ?? string.Empty; } } @@ -890,6 +932,7 @@ namespace System.Xml FinishOtherValueIterator(); } } + return _curNode.StringValue; } } @@ -904,7 +947,7 @@ namespace System.Xml } // Returns the base URI of the current node. - public override string BaseURI + public override string? BaseURI { get { @@ -1003,7 +1046,7 @@ namespace System.Xml } // Returns value of an attribute with the specified Name - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { int i; if (!name.Contains(':')) @@ -1014,21 +1057,24 @@ namespace System.Xml { i = GetIndexOfAttributeWithPrefix(name); } + return (i >= 0) ? _nodes[i].StringValue : null; } // Returns value of an attribute with the specified LocalName and NamespaceURI - public override string GetAttribute(string localName, string namespaceURI) + public override string? GetAttribute(string localName, string? namespaceURI) { namespaceURI = (namespaceURI == null) ? string.Empty : _nameTable.Get(namespaceURI); - localName = _nameTable.Get(localName); + string? localNameAtomized = _nameTable.Get(localName); + for (int i = _index + 1; i < _index + _attrCount + 1; i++) { - if (Ref.Equal(_nodes[i].localName, localName) && Ref.Equal(_nodes[i].ns, namespaceURI)) + if (Ref.Equal(_nodes[i].localName, localNameAtomized) && Ref.Equal(_nodes[i].ns, namespaceURI)) { return _nodes[i].StringValue; } } + return null; } @@ -1039,6 +1085,7 @@ namespace System.Xml { throw new ArgumentOutOfRangeException(nameof(i)); } + return _nodes[_index + i + 1].StringValue; } @@ -1074,12 +1121,12 @@ namespace System.Xml // Moves to an attribute with the specified LocalName and NamespceURI public override bool MoveToAttribute(string localName, string namespaceURI) { - namespaceURI = (namespaceURI == null) ? string.Empty : _nameTable.Get(namespaceURI); - localName = _nameTable.Get(localName); + string? namespaceURIAtomized = (namespaceURI == null) ? string.Empty : _nameTable.Get(namespaceURI); + string? localNameAtomized = _nameTable.Get(localName); for (int i = _index + 1; i < _index + _attrCount + 1; i++) { - if (Ref.Equal(_nodes[i].localName, localName) && - Ref.Equal(_nodes[i].ns, namespaceURI)) + if (Ref.Equal(_nodes[i].localName, localNameAtomized) && + Ref.Equal(_nodes[i].ns, namespaceURIAtomized)) { _curAttrIndex = i - _index - 1; _curNode = _nodes[i]; @@ -1091,6 +1138,7 @@ namespace System.Xml return true; } } + return false; } @@ -1106,6 +1154,7 @@ namespace System.Xml { FinishAttributeValueIterator(); } + _curAttrIndex = i; _curNode = _nodes[_index + 1 + _curAttrIndex]; } @@ -1164,6 +1213,8 @@ namespace System.Xml private void FinishInit() { + Debug.Assert(_laterInitParam != null); + switch (_laterInitParam.initType) { case InitInputType.UriString: @@ -1375,13 +1426,14 @@ namespace System.Xml } // Returns NamespaceURI associated with the specified prefix in the current namespace scope. - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { if (!_supportNamespaces) { return null; } + Debug.Assert(_namespaceManager != null); return _namespaceManager.LookupNamespace(prefix); } @@ -1495,7 +1547,7 @@ namespace System.Xml case EntityType.ExpandedInAttribute: case EntityType.Expanded: _nextParsingFunction = _parsingFunction; - if (_ps.charsUsed - _ps.charPos == 0 && !_ps.entity.IsExternal) + if (_ps.charsUsed - _ps.charPos == 0 && !_ps.entity!.IsExternal) { // empty internal entity value _parsingFunction = ParsingFunction.AfterResolveEmptyEntityInContent; } @@ -1897,6 +1949,8 @@ namespace System.Xml { copyCount = endPos - startPos; } + + Debug.Assert(_ps.chars != null); BlockCopyChars(_ps.chars, startPos, buffer, (index + readCount), copyCount); readCount += copyCount; @@ -1920,6 +1974,7 @@ namespace System.Xml } _readValueOffset = 0; + Debug.Assert(_ps.chars != null); _curNode.SetValue(_ps.chars, startPos, endPos - startPos); } return readCount; @@ -1959,12 +2014,12 @@ namespace System.Xml return this.GetNamespacesInScope(scope); } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { return this.LookupNamespace(prefix); } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { return this.LookupPrefix(namespaceName); } @@ -1972,13 +2027,15 @@ namespace System.Xml // Internal IXmlNamespaceResolver methods internal IDictionary GetNamespacesInScope(XmlNamespaceScope scope) { + Debug.Assert(_namespaceManager != null); return _namespaceManager.GetNamespacesInScope(scope); } // NOTE: there already is virtual method for "string LookupNamespace(string prefix)" - internal string LookupPrefix(string namespaceName) + internal string? LookupPrefix(string namespaceName) { + Debug.Assert(_namespaceManager != null); return _namespaceManager.LookupPrefix(namespaceName); } @@ -1998,6 +2055,7 @@ namespace System.Xml { throw new InvalidOperationException(SR.Xml_InvalidOperation); } + _supportNamespaces = value; if (value) { @@ -2012,7 +2070,9 @@ namespace System.Xml _namespaceManager = new XmlNamespaceManager(_nameTable); } } - _xmlContext.defaultNamespace = _namespaceManager.LookupNamespace(string.Empty); + + Debug.Assert(_namespaceManager != null); + _xmlContext.defaultNamespace = _namespaceManager.LookupNamespace(string.Empty)!; } else { @@ -2020,6 +2080,7 @@ namespace System.Xml { _namespaceManager = new NoNamespaceManager(); } + _xmlContext.defaultNamespace = string.Empty; } } @@ -2050,7 +2111,7 @@ namespace System.Xml } // Returns the Encoding of the XML document - internal Encoding Encoding + internal Encoding? Encoding { get { @@ -2078,6 +2139,7 @@ namespace System.Xml { throw new XmlException(SR.Xml_WhitespaceHandling, string.Empty); } + _whitespaceHandling = value; } } @@ -2098,6 +2160,7 @@ namespace System.Xml { throw new ArgumentOutOfRangeException(nameof(value)); } + _dtdProcessing = value; } } @@ -2115,6 +2178,7 @@ namespace System.Xml { throw new XmlException(SR.Xml_EntityHandling, string.Empty); } + _entityHandling = value; } } @@ -2134,9 +2198,10 @@ namespace System.Xml _xmlResolverIsSet = true; // invalidate all baseUris on the stack _ps.baseUri = null; + for (int i = 0; i <= _parsingStatesStackTop; i++) { - _parsingStatesStack[i].baseUri = null; + _parsingStatesStack![i].baseUri = null; } } } @@ -2158,6 +2223,7 @@ namespace System.Xml // Clear ResetAttributes(); + Debug.Assert(_namespaceManager != null); while (_namespaceManager.PopScope()) ; while (InEntity) @@ -2186,7 +2252,6 @@ namespace System.Xml internal TextReader GetRemainder() { Debug.Assert(_v1Compat, "XmlTextReaderImpl.GetRemainder cannot be called on reader created via XmlReader.Create."); - Debug.Assert(_stringBuilder.Length == 0); switch (_parsingFunction) { @@ -2350,7 +2415,7 @@ namespace System.Xml } } - internal IXmlNamespaceResolver DtdParserProxy_NamespaceResolver + internal IXmlNamespaceResolver? DtdParserProxy_NamespaceResolver { get { @@ -2390,7 +2455,7 @@ namespace System.Xml } } - internal Uri DtdParserProxy_BaseUri + internal Uri? DtdParserProxy_BaseUri { // SxS: ps.baseUri may be initialized in the constructor (public XmlTextReaderImpl( string url, XmlNameTable nt )) based on // url provided by the user. Here the property returns ps.BaseUri - so it may expose a path. @@ -2400,6 +2465,7 @@ namespace System.Xml { _ps.baseUri = _xmlResolver.ResolveUri(null, _ps.baseUriStr); } + return _ps.baseUri; } } @@ -2412,7 +2478,7 @@ namespace System.Xml } } - internal char[] DtdParserProxy_ParsingBuffer + internal char[]? DtdParserProxy_ParsingBuffer { get { @@ -2457,7 +2523,7 @@ namespace System.Xml } } - internal IValidationEventHandling DtdParserProxy_ValidationEventHandling + internal IValidationEventHandling? DtdParserProxy_ValidationEventHandling { get { @@ -2592,7 +2658,7 @@ namespace System.Xml return retValue; } - internal bool DtdParserProxy_PopEntity(out IDtdEntityInfo oldEntity, out int newEntityId) + internal bool DtdParserProxy_PopEntity(out IDtdEntityInfo? oldEntity, out int newEntityId) { if (_parsingStatesStackTop == -1) { @@ -2600,6 +2666,7 @@ namespace System.Xml newEntityId = -1; return false; } + oldEntity = _ps.entity; PopEntity(); newEntityId = _ps.entityId; @@ -2608,7 +2675,7 @@ namespace System.Xml // SxS: The caller did not provide any SxS sensitive name or resource. No resource is being exposed either. // It is OK to suppress SxS warning. - internal bool DtdParserProxy_PushExternalSubset(string systemId, string publicId) + internal bool DtdParserProxy_PushExternalSubset(string? systemId, string? publicId) { Debug.Assert(_parsingStatesStackTop == -1); Debug.Assert((systemId != null && systemId.Length > 0) || (publicId != null && publicId.Length > 0)); @@ -2617,10 +2684,14 @@ namespace System.Xml { return false; } + + Debug.Assert(_xmlResolver != null); + if (_ps.baseUri == null && !string.IsNullOrEmpty(_ps.baseUriStr)) { _ps.baseUri = _xmlResolver.ResolveUri(null, _ps.baseUriStr); } + PushExternalEntityOrSubset(publicId, systemId, _ps.baseUri, null); _ps.entity = null; @@ -2679,90 +2750,108 @@ namespace System.Xml // // Throw methods: Sets the reader current position to pos, sets the error state and throws exception // + [DoesNotReturn] private void Throw(int pos, string res, string arg) { _ps.charPos = pos; Throw(res, arg); } + [DoesNotReturn] private void Throw(int pos, string res, string[] args) { _ps.charPos = pos; Throw(res, args); } + [DoesNotReturn] private void Throw(int pos, string res) { _ps.charPos = pos; Throw(res, string.Empty); } + [DoesNotReturn] private void Throw(string res) { Throw(res, string.Empty); } + [DoesNotReturn] private void Throw(string res, int lineNo, int linePos) { Throw(new XmlException(res, string.Empty, lineNo, linePos, _ps.baseUriStr)); } - private void Throw(string res, string arg) + [DoesNotReturn] + private void Throw(string res, string? arg) { Throw(new XmlException(res, arg, _ps.LineNo, _ps.LinePos, _ps.baseUriStr)); } - private void Throw(string res, string arg, int lineNo, int linePos) + [DoesNotReturn] + private void Throw(string res, string? arg, int lineNo, int linePos) { Throw(new XmlException(res, arg, lineNo, linePos, _ps.baseUriStr)); } - private void Throw(string res, string[] args) + [DoesNotReturn] + private void Throw(string res, string?[] args) { Throw(new XmlException(res, args, _ps.LineNo, _ps.LinePos, _ps.baseUriStr)); } - private void Throw(string res, string arg, Exception innerException) + [DoesNotReturn] + private void Throw(string res, string? arg, Exception innerException) { - Throw(res, new string[] { arg }, innerException); + Throw(res, new string?[] { arg }, innerException); } - private void Throw(string res, string[] args, Exception innerException) + [DoesNotReturn] + private void Throw(string res, string?[] args, Exception innerException) { Throw(new XmlException(res, args, innerException, _ps.LineNo, _ps.LinePos, _ps.baseUriStr)); } + [DoesNotReturn] private void Throw(Exception e) { SetErrorState(); - XmlException xmlEx = e as XmlException; + XmlException? xmlEx = e as XmlException; + if (xmlEx != null) { _curNode.SetLineInfo(xmlEx.LineNumber, xmlEx.LinePosition); } + throw e; } + [DoesNotReturn] private void ReThrow(Exception e, int lineNo, int linePos) { - Throw(new XmlException(e.Message, (Exception)null, lineNo, linePos, _ps.baseUriStr)); + Throw(new XmlException(e.Message, (Exception?)null, lineNo, linePos, _ps.baseUriStr)); } + [DoesNotReturn] private void ThrowWithoutLineInfo(string res) { Throw(new XmlException(res, string.Empty, _ps.baseUriStr)); } + [DoesNotReturn] private void ThrowWithoutLineInfo(string res, string arg) { Throw(new XmlException(res, arg, _ps.baseUriStr)); } - private void ThrowWithoutLineInfo(string res, string[] args, Exception innerException) + [DoesNotReturn] + private void ThrowWithoutLineInfo(string res, string?[] args, Exception? innerException) { Throw(new XmlException(res, args, innerException, 0, 0, _ps.baseUriStr)); } + [DoesNotReturn] private void ThrowInvalidChar(char[] data, int length, int invCharPos) { Throw(invCharPos, SR.Xml_InvalidCharacter, XmlException.BuildCharExceptionArgs(data, length, invCharPos)); @@ -2774,7 +2863,7 @@ namespace System.Xml _readState = ReadState.Error; } - private void SendValidationEvent(XmlSeverityType severity, string code, string arg, int lineNo, int linePos) + private void SendValidationEvent(XmlSeverityType severity, string code, string? arg, int lineNo, int linePos) { SendValidationEvent(severity, new XmlSchemaException(code, arg, _ps.baseUriStr, lineNo, linePos)); } @@ -2809,6 +2898,7 @@ namespace System.Xml { FinishReadContentAsBinary(); } + if (_parsingFunction == ParsingFunction.InReadAttributeValue) { while (_ps.entityId != _attributeValueBaseEntityId) @@ -2829,29 +2919,29 @@ namespace System.Xml } } - private void InitStreamInput(Stream stream, Encoding encoding) + private void InitStreamInput(Stream stream, Encoding? encoding) { InitStreamInput(null, string.Empty, stream, null, 0, encoding); } - private void InitStreamInput(string baseUriStr, Stream stream, Encoding encoding) + private void InitStreamInput(string baseUriStr, Stream stream, Encoding? encoding) { Debug.Assert(baseUriStr != null); InitStreamInput(null, baseUriStr, stream, null, 0, encoding); } - private void InitStreamInput(Uri baseUri, Stream stream, Encoding encoding) + private void InitStreamInput(Uri? baseUri, Stream stream, Encoding? encoding) { Debug.Assert(baseUri != null); InitStreamInput(baseUri, baseUri.ToString(), stream, null, 0, encoding); } - private void InitStreamInput(Uri baseUri, string baseUriStr, Stream stream, Encoding encoding) + private void InitStreamInput(Uri? baseUri, string baseUriStr, Stream stream, Encoding? encoding) { InitStreamInput(baseUri, baseUriStr, stream, null, 0, encoding); } - private void InitStreamInput(Uri baseUri, string baseUriStr, Stream stream, byte[] bytes, int byteCount, Encoding encoding) + private void InitStreamInput(Uri? baseUri, string baseUriStr, Stream stream, byte[]? bytes, int byteCount, Encoding? encoding) { Debug.Assert(_ps.charPos == 0 && _ps.charsUsed == 0 && _ps.textReader == null); Debug.Assert(baseUriStr != null); @@ -2910,6 +3000,7 @@ namespace System.Xml { encoding = DetectEncoding(); } + SetupEncoding(encoding); // eat preamble @@ -2929,7 +3020,7 @@ namespace System.Xml InitTextReaderInput(baseUriStr, null, input); } - private void InitTextReaderInput(string baseUriStr, Uri baseUri, TextReader input) + private void InitTextReaderInput(string baseUriStr, Uri? baseUri, TextReader input) { Debug.Assert(_ps.charPos == 0 && _ps.charsUsed == 0 && _ps.stream == null); Debug.Assert(baseUriStr != null); @@ -2958,7 +3049,7 @@ namespace System.Xml ReadData(); } - private void InitStringInput(string baseUriStr, Encoding originalEncoding, string str) + private void InitStringInput(string baseUriStr, Encoding? originalEncoding, string str) { Debug.Assert(_ps.stream == null && _ps.textReader == null); Debug.Assert(_ps.charPos == 0 && _ps.charsUsed == 0); @@ -2980,7 +3071,7 @@ namespace System.Xml _ps.isEof = true; } - private void InitFragmentReader(XmlNodeType fragmentType, XmlParserContext parserContext, bool allowXmlDeclFragment) + private void InitFragmentReader(XmlNodeType fragmentType, XmlParserContext? parserContext, bool allowXmlDeclFragment) { _fragmentParserContext = parserContext; @@ -2989,7 +3080,7 @@ namespace System.Xml if (parserContext.NamespaceManager != null) { _namespaceManager = parserContext.NamespaceManager; - _xmlContext.defaultNamespace = _namespaceManager.LookupNamespace(string.Empty); + _xmlContext.defaultNamespace = _namespaceManager.LookupNamespace(string.Empty)!; } else { @@ -3041,6 +3132,7 @@ namespace System.Xml Throw(SR.Xml_PartialContentNodeTypeNotSupportedEx, fragmentType.ToString()); return; } + _fragmentType = fragmentType; _fragment = true; } @@ -3081,7 +3173,7 @@ namespace System.Xml try { - _ps.stream = (Stream)tmpResolver.GetEntity(_ps.baseUri, null, typeof(Stream)); + _ps.stream = (Stream?)tmpResolver.GetEntity(_ps.baseUri, null, typeof(Stream)); } catch { @@ -3094,12 +3186,13 @@ namespace System.Xml ThrowWithoutLineInfo(SR.Xml_CannotResolveUrl, _ps.baseUriStr); } + Debug.Assert(_ps.stream != null); InitStreamInput(_ps.baseUri, _ps.baseUriStr, _ps.stream, null); _reportedEncoding = _ps.encoding; } // Stream input only: detect encoding from the first 4 bytes of the byte buffer starting at ps.bytes[ps.bytePos] - private Encoding DetectEncoding() + private Encoding? DetectEncoding() { Debug.Assert(_ps.bytes != null); Debug.Assert(_ps.bytePos == 0); @@ -3108,6 +3201,7 @@ namespace System.Xml { return null; } + int first2Bytes = _ps.bytes[0] << 8 | _ps.bytes[1]; int next2Bytes = (_ps.bytesUsed >= 4) ? (_ps.bytes[2] << 8 | _ps.bytes[3]) : 0; @@ -3183,7 +3277,7 @@ namespace System.Xml return null; } - private void SetupEncoding(Encoding encoding) + private void SetupEncoding(Encoding? encoding) { if (encoding == null) { @@ -3205,6 +3299,8 @@ namespace System.Xml private void EatPreamble() { + Debug.Assert(_ps.encoding != null); + Debug.Assert(_ps.bytes != null); ReadOnlySpan preamble = _ps.encoding.Preamble; int preambleLen = preamble.Length; int i; @@ -3224,6 +3320,7 @@ namespace System.Xml // Switches the reader's encoding private void SwitchEncoding(Encoding newEncoding) { + Debug.Assert(_ps.encoding != null); if ((newEncoding.WebName != _ps.encoding.WebName || _ps.decoder is SafeAsciiDecoder) && !_afterResetState) { Debug.Assert(_ps.stream != null); @@ -3238,6 +3335,8 @@ namespace System.Xml // Performs checks whether switching from current encoding to specified encoding is allowed. private Encoding CheckEncoding(string newEncodingName) { + Debug.Assert(_ps.encoding != null); + // encoding can be switched on stream input only if (_ps.stream == null) { @@ -3265,7 +3364,7 @@ namespace System.Xml return _ps.encoding; } - Encoding newEncoding = null; + Encoding? newEncoding = null; if (string.Equals(newEncodingName, "utf-8", StringComparison.OrdinalIgnoreCase)) { newEncoding = UTF8BomThrowing; @@ -3284,6 +3383,8 @@ namespace System.Xml { Throw(SR.Xml_UnknownEncoding, newEncodingName, innerEx); } + + Debug.Assert(newEncoding != null); Debug.Assert(newEncoding.EncodingName != "UTF-8"); } @@ -3313,6 +3414,7 @@ namespace System.Xml "We didn't correctly count some of the decoded characters against the MaxCharactersInDocument."); _charactersInDocument -= _ps.charsUsed - _ps.charPos; } + if (_maxCharactersFromEntities > 0) { if (InEntity) @@ -3326,8 +3428,11 @@ namespace System.Xml _ps.bytePos = _documentStartBytePos; // byte position after preamble if (_ps.charPos > 0) { + Debug.Assert(_ps.encoding != null); + Debug.Assert(_ps.chars != null); _ps.bytePos += _ps.encoding.GetByteCount(_ps.chars, 0, _ps.charPos); } + _ps.charsUsed = _ps.charPos; _ps.isEof = false; } @@ -3350,6 +3455,7 @@ namespace System.Xml return 0; } + Debug.Assert(_ps.chars != null); int charsRead; if (_ps.appendMode) { @@ -3372,6 +3478,7 @@ namespace System.Xml // the byte buffer is full -> allocate a new one if (_ps.bytesUsed - _ps.bytePos < MaxByteSequenceLen) { + Debug.Assert(_ps.bytes != null); if (_ps.bytes.Length - _ps.bytesUsed < MaxByteSequenceLen) { byte[] newBytes = new byte[_ps.bytes.Length * 2]; @@ -3430,9 +3537,11 @@ namespace System.Xml } else { + Debug.Assert(_ps.bytes != null); BlockCopy(_ps.bytes, _ps.bytePos, _ps.bytes, 0, bytesLeft); _ps.bytesUsed = bytesLeft; } + _ps.bytePos = 0; } } @@ -3443,6 +3552,8 @@ namespace System.Xml { if (!_ps.isStreamEof) { + Debug.Assert(_ps.bytes != null); + // read new bytes if (_ps.bytePos == _ps.bytesUsed && _ps.bytes.Length - _ps.bytesUsed > 0) { @@ -3483,6 +3594,7 @@ namespace System.Xml Debug.Assert(_ps.charsUsed < _ps.chars.Length); _ps.isEof = true; } + _ps.chars[_ps.charsUsed] = (char)0; return charsRead; } @@ -3491,6 +3603,7 @@ namespace System.Xml private int GetChars(int maxCharsCount) { Debug.Assert(_ps.stream != null && _ps.decoder != null && _ps.bytes != null); + Debug.Assert(_ps.chars != null); Debug.Assert(maxCharsCount <= _ps.chars.Length - _ps.charsUsed - 1); // determine the maximum number of bytes we can pass to the decoder @@ -3530,10 +3643,14 @@ namespace System.Xml int chDec; int bDec; bool completed; + Debug.Assert(_ps.decoder != null); + Debug.Assert(_ps.bytes != null); + Debug.Assert(_ps.chars != null); _ps.decoder.Convert(_ps.bytes, _ps.bytePos + bytesDecoded, 1, _ps.chars, _ps.charsUsed + charsDecoded, 2, false, out bDec, out chDec, out completed); charsDecoded += chDec; bytesDecoded += bDec; } + Debug.Fail("We should get an exception again."); } catch (ArgumentException) @@ -3544,6 +3661,7 @@ namespace System.Xml { Throw(_ps.charsUsed, SR.Xml_InvalidCharInThisEncoding); } + charsCount = charsDecoded; bytesCount = bytesDecoded; } @@ -3575,6 +3693,7 @@ namespace System.Xml private void ShiftBuffer(int sourcePos, int destPos, int count) { + Debug.Assert(_ps.chars != null); BlockCopyChars(_ps.chars, sourcePos, _ps.chars, destPos, count); } @@ -3590,7 +3709,7 @@ namespace System.Xml } if (!XmlConvert.StrEqual(_ps.chars, _ps.charPos, 5, XmlDeclarationBeginning) || - _xmlCharType.IsNameSingleChar(_ps.chars[_ps.charPos + 5]) + _xmlCharType.IsNameSingleChar(_ps.chars![_ps.charPos + 5]) #if XML10_FIFTH_EDITION || xmlCharType.IsNCNameHighSurrogateChar( ps.chars[ps.charPos + 5] ) #endif @@ -3604,6 +3723,7 @@ namespace System.Xml _curNode.SetLineInfo(_ps.LineNo, _ps.LinePos + 2); _curNode.SetNamedNode(XmlNodeType.XmlDeclaration, _xml); } + _ps.charPos += 5; // parsing of text declarations cannot change global stringBuidler or curNode as we may be in the middle of a text node @@ -3612,7 +3732,7 @@ namespace System.Xml // parse version, encoding & standalone attributes int xmlDeclState = 0; // - Encoding encoding = null; + Encoding? encoding = null; while (true) { @@ -3651,6 +3771,7 @@ namespace System.Xml if (_afterResetState) { // check for invalid encoding switches to default encoding + Debug.Assert(_ps.encoding != null); string encodingName = _ps.encoding.WebName; if (encodingName != "utf-8" && encodingName != "utf-16" && encodingName != "utf-16BE" && !(_ps.encoding is Ucs4Encoding)) @@ -3688,7 +3809,7 @@ namespace System.Xml // read attribute name int nameEndPos = ParseName(); - NodeData attr = null; + NodeData? attr = null; switch (_ps.chars[_ps.charPos]) { case 'v': @@ -3729,8 +3850,10 @@ namespace System.Xml Throw(isTextDecl ? SR.Xml_InvalidTextDecl : SR.Xml_InvalidXmlDecl); break; } + if (!isTextDecl) { + Debug.Assert(attr != null); attr.SetLineInfo(_ps.LineNo, _ps.LinePos); } sb.Append(_ps.chars, _ps.charPos, nameEndPos - _ps.charPos); @@ -3762,6 +3885,7 @@ namespace System.Xml _ps.charPos++; if (!isTextDecl) { + Debug.Assert(attr != null); attr.quoteChar = quoteChar; attr.SetLineInfo2(_ps.LineNo, _ps.LinePos); } @@ -3796,6 +3920,7 @@ namespace System.Xml #endif if (!isTextDecl) { + Debug.Assert(attr != null); attr.SetValue(_ps.chars, _ps.charPos, pos - _ps.charPos); } xmlDeclState = 1; @@ -3811,6 +3936,7 @@ namespace System.Xml encoding = CheckEncoding(encName); if (!isTextDecl) { + Debug.Assert(attr != null); attr.SetValue(encName); } xmlDeclState = 2; @@ -3831,6 +3957,7 @@ namespace System.Xml } if (!isTextDecl) { + Debug.Assert(attr != null); attr.SetValue(_ps.chars, _ps.charPos, pos - _ps.charPos); } xmlDeclState = 3; @@ -3876,6 +4003,7 @@ namespace System.Xml if (_afterResetState) { // check for invalid encoding switches to default encoding + Debug.Assert(_ps.encoding != null); string encodingName = _ps.encoding.WebName; if (encodingName != "utf-8" && encodingName != "utf-16" && encodingName != "utf-16BE" && !(_ps.encoding is Ucs4Encoding)) @@ -3907,6 +4035,7 @@ namespace System.Xml { bool needMoreChars = false; int pos = _ps.charPos; + Debug.Assert(_ps.chars != null); char[] chars = _ps.chars; // some tag @@ -4141,6 +4270,7 @@ namespace System.Xml while (true) { int pos = _ps.charPos; + Debug.Assert(_ps.chars != null); char[] chars = _ps.chars; switch (chars[pos]) @@ -4305,6 +4435,7 @@ namespace System.Xml _stringBuilder.Append('.'); } } + Throw(_ps.charsUsed, SR.Xml_UnexpectedEOFInElementContent, _stringBuilder.ToString()); } } @@ -4313,6 +4444,7 @@ namespace System.Xml private void ParseElement() { int pos = _ps.charPos; + Debug.Assert(_ps.chars != null); char[] chars = _ps.chars; int colonPos = -1; @@ -4390,6 +4522,7 @@ namespace System.Xml SetElement: // push namespace context + Debug.Assert(_namespaceManager != null); _namespaceManager.PushScope(); // init the NodeData class @@ -4482,8 +4615,9 @@ namespace System.Xml private void AddDefaultAttributesAndNormalize() { Debug.Assert(_curNode.type == XmlNodeType.Element); + Debug.Assert(_dtdInfo != null); + IDtdAttributeListInfo? attlistInfo = _dtdInfo.LookupAttributeList(_curNode.localName, _curNode.prefix); - IDtdAttributeListInfo attlistInfo = _dtdInfo.LookupAttributeList(_curNode.localName, _curNode.prefix); if (attlistInfo == null) { return; @@ -4525,7 +4659,7 @@ namespace System.Xml if (defaultAttributes != null) { int originalAttrCount = _attrCount; - NodeData[] nameSortedAttributes = null; + NodeData[]? nameSortedAttributes = null; if (_attrCount >= MaxAttrDuplWalkCount) { @@ -4573,6 +4707,7 @@ namespace System.Xml } int nameLen; + Debug.Assert(_ps.chars != null); char[] chars = _ps.chars; if (startTagNode.prefix.Length == 0) { @@ -4688,6 +4823,7 @@ namespace System.Xml int colonPos; int endPos = ParseQName(out colonPos); + Debug.Assert(_ps.chars != null); string[] args = new string[4]; args[0] = startTag.GetNameWPrefix(_nameTable); args[1] = startTag.lineInfo.lineNo.ToString(CultureInfo.InvariantCulture); @@ -4706,8 +4842,9 @@ namespace System.Xml private void ParseAttributes() { int pos = _ps.charPos; + Debug.Assert(_ps.chars != null); char[] chars = _ps.chars; - NodeData attr = null; + NodeData? attr = null; Debug.Assert(_attrCount == 0); @@ -5085,6 +5222,7 @@ namespace System.Xml { PushXmlContext(); } + _xmlContext.defaultNamespace = ns; AddNamespace(string.Empty, ns, attr); @@ -5114,6 +5252,7 @@ namespace System.Xml { PushXmlContext(); } + switch (XmlConvert.TrimString(attr.StringValue)) { case "preserve": @@ -5133,6 +5272,7 @@ namespace System.Xml { PushXmlContext(); } + _xmlContext.xmlLang = attr.StringValue; break; } @@ -5141,11 +5281,12 @@ namespace System.Xml private void ParseAttributeValueSlow(int curPos, char quoteChar, NodeData attr) { int pos = curPos; + Debug.Assert(_ps.chars != null); char[] chars = _ps.chars; int attributeBaseEntityId = _ps.entityId; int valueChunkStartPos = 0; LineInfo valueChunkLineInfo = new LineInfo(_ps.lineNo, _ps.LinePos); - NodeData lastChunk = null; + NodeData? lastChunk = null; Debug.Assert(_stringBuilder.Length == 0); @@ -5302,6 +5443,7 @@ namespace System.Xml NodeData entityChunk = new NodeData(); entityChunk.lineInfo = entityLineInfo; entityChunk.depth = attr.depth + 1; + Debug.Assert(_ps.entity != null); entityChunk.SetNamedNode(XmlNodeType.EntityReference, _ps.entity.Name); AddAttributeChunkToList(attr, entityChunk, ref lastChunk); @@ -5412,7 +5554,7 @@ namespace System.Xml _stringBuilder.Length = 0; } - private void AddAttributeChunkToList(NodeData attr, NodeData chunk, ref NodeData lastChunk) + private void AddAttributeChunkToList(NodeData attr, NodeData chunk, ref NodeData? lastChunk) { if (lastChunk == null) { @@ -5454,12 +5596,15 @@ namespace System.Xml { goto IgnoredNode; } + XmlNodeType nodeType = GetTextNodeType(orChars); if (nodeType == XmlNodeType.None) { goto IgnoredNode; } + Debug.Assert(endPos - startPos > 0); + Debug.Assert(_ps.chars != null); _curNode.SetValueNode(nodeType, _ps.chars, startPos, endPos - startPos); return true; } @@ -5504,6 +5649,7 @@ namespace System.Xml if (orChars > 0x20) { Debug.Assert(endPos - startPos > 0); + Debug.Assert(_ps.chars != null); _curNode.SetValueNode(XmlNodeType.Text, _ps.chars, startPos, endPos - startPos); _nextParsingFunction = _parsingFunction; _parsingFunction = ParsingFunction.PartialTextValue; @@ -5536,6 +5682,7 @@ namespace System.Xml } goto IgnoredNode; } + // set value to curNode _curNode.SetValueNode(nodeType, _stringBuilder.ToString()); _stringBuilder.Length = 0; @@ -5546,6 +5693,7 @@ namespace System.Xml _nextParsingFunction = _parsingFunction; _parsingFunction = ParsingFunction.PartialTextValue; } + return true; } } @@ -5576,6 +5724,7 @@ namespace System.Xml // Returns true when the whole value has been parsed. Return false when it needs to be called again to get a next chunk of value. private bool ParseText(out int startPos, out int endPos, ref int outOrChars) { + Debug.Assert(_ps.chars != null); char[] chars = _ps.chars; int pos = _ps.charPos; int rcount = 0; @@ -5943,6 +6092,7 @@ namespace System.Xml XmlNodeType nodeType = GetWhitespaceType(); + Debug.Assert(_ps.chars != null); if (nodeType == XmlNodeType.None) { EatWhitespaces(null); @@ -5980,6 +6130,7 @@ namespace System.Xml private void ParseEntityReference() { + Debug.Assert(_ps.chars != null); Debug.Assert(_ps.chars[_ps.charPos] == '&'); _ps.charPos++; @@ -5989,6 +6140,7 @@ namespace System.Xml private EntityType HandleEntityReference(bool isInAttributeValue, EntityExpandType expandType, out int charRefEndPos) { + Debug.Assert(_ps.chars != null); Debug.Assert(_ps.chars[_ps.charPos] == '&'); if (_ps.charPos + 1 == _ps.charsUsed) @@ -6062,7 +6214,7 @@ namespace System.Xml // return false == unexpanded external entity, stop parsing and return private EntityType HandleGeneralEntityReference(string name, bool isInAttributeValue, bool pushFakeEntityIfNullResolver, int entityStartLinePos) { - IDtdEntityInfo entity = null; + IDtdEntityInfo? entity = null; if (_dtdInfo == null && _fragmentParserContext != null && _fragmentParserContext.HasDtdInfo && _dtdProcessing == DtdProcessing.Parse) { @@ -6082,6 +6234,8 @@ namespace System.Xml Throw(SR.Xml_UndeclaredEntity, name, _ps.LineNo, entityStartLinePos); } + Debug.Assert(entity != null); + if (entity.IsUnparsedEntity) { if (_disableUndeclaredEntityCheck) @@ -6217,6 +6371,7 @@ namespace System.Xml { _curNode = _nodes[_index + _attrCount + 1]; Debug.Assert(_curNode.type == XmlNodeType.EntityReference); + Debug.Assert(_lastEntity != null); Debug.Assert(Ref.Equal(_lastEntity.Name, _curNode.localName)); _curNode.lineInfo.linePos += _curNode.localName.Length; _curNode.type = XmlNodeType.EndEntity; @@ -6229,7 +6384,7 @@ namespace System.Xml // Parses processing instruction; if piInDtdStringBuilder != null, the processing instruction is in DTD and // it will be saved in the passed string builder (target, whitespace & value). - private bool ParsePI(StringBuilder piInDtdStringBuilder) + private bool ParsePI(StringBuilder? piInDtdStringBuilder) { if (_parsingMode == ParsingMode.Full) { @@ -6240,6 +6395,7 @@ namespace System.Xml // parse target name int nameEndPos = ParseName(); + Debug.Assert(_ps.chars != null); string target = _nameTable.Add(_ps.chars, _ps.charPos, nameEndPos - _ps.charPos); if (string.Equals(target, "xml", StringComparison.OrdinalIgnoreCase)) @@ -6325,6 +6481,7 @@ namespace System.Xml _stringBuilder.Length = 0; } } + return true; } @@ -6339,6 +6496,7 @@ namespace System.Xml } } + Debug.Assert(_ps.chars != null); int pos = _ps.charPos; char[] chars = _ps.chars; int rcount = 0; @@ -6510,6 +6668,7 @@ namespace System.Xml Debug.Assert(_stringBuilder.Length == 0); if (ParseCDataOrComment(type, out startPos, out endPos)) { + Debug.Assert(_ps.chars != null); _curNode.SetValueNode(type, _ps.chars, startPos, endPos - startPos); } else @@ -6518,6 +6677,7 @@ namespace System.Xml { _stringBuilder.Append(_ps.chars, startPos, endPos - startPos); } while (!ParseCDataOrComment(type, out startPos, out endPos)); + _stringBuilder.Append(_ps.chars, startPos, endPos - startPos); _curNode.SetValueNode(type, _stringBuilder.ToString()); _stringBuilder.Length = 0; @@ -6541,6 +6701,7 @@ namespace System.Xml } } + Debug.Assert(_ps.chars != null); int pos = _ps.charPos; char[] chars = _ps.chars; int rcount = 0; @@ -6707,10 +6868,13 @@ namespace System.Xml Throw(SR.Xml_UnexpectedEOF, "DOCTYPE"); } } + if (!XmlConvert.StrEqual(_ps.chars, _ps.charPos, 7, "DOCTYPE")) { ThrowUnexpectedToken((!_rootElementParsed && _dtdInfo == null) ? "DOCTYPE" : "