Closed simon-curtis closed 1 year ago
We have got around the above error by unwrapping the FirstOrDefault
BaseElement? type = null;
foreach (var childNode in _root.Descendants.TakeWhile(_ => type is null))
{
if (childNode.Name == "xs:attribute"
|| GetAttribute<string>(childNode, "name") != inheritedTypeName
|| childNode.IsNull)
continue;
type = Visit(childNode) with { Name = name ?? inheritedTypeName };
}
And we have subsequently now hit another exception, from a seperate call, throwing in the XmlNodeList.FirstOrDefault
method
public Option<XmlNode> FirstOrDefault(Func<XmlNode, bool> predicate)
{
if (predicate == null)
ThrowHelper.ThrowNullArg(nameof (predicate));
foreach (XmlNode xmlNode in this)
{
if (predicate(xmlNode))
return (Option<XmlNode>) ref xmlNode;
}
return Option<XmlNode>.Null;
}
I have created my own FindNode method using boxing
private static Option<XmlNode> FindNode(IEnumerable<XmlNode> list, Func<StrongBox<XmlNode>, bool> predicate)
{
foreach (var xmlNode in list.Where(xmlNode => predicate(new StrongBox<XmlNode>(xmlNode))))
return (Option<XmlNode>) xmlNode;
return Option<XmlNode>.Null;
}
unfortunately this didn't work either
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.SpanHelpers.SequenceEqual(Byte ByRef, Byte ByRef, UIntPtr)
at U8Xml.XmlAttributeEnumerableExtension.FindOrDefault[[U8Xml.XmlAttributeList, U8XmlParser, Version=1.6.1.0, Culture=neutral, PublicKeyToken=null]](U8Xml.XmlAttributeList, System.ReadOnlySpan`1<Byte>)
at U8Xml.XmlAttributeEnumerableExtension.FindOrDefault[[U8Xml.XmlAttributeList, U8XmlParser, Version=1.6.1.0, Culture=neutral, PublicKeyToken=null]](U8Xml.XmlAttributeList, System.ReadOnlySpan`1<Char>)
at CMA.Common.Xml.Validation.Xsd.XsdParser+<>c__DisplayClass14_0.<VisitElement>b__1(System.Runtime.CompilerServices.StrongBox`1<U8Xml.XmlNode>)
at CMA.Common.Xml.Validation.Xsd.XsdParser+<>c__DisplayClass15_0.<FindNode>b__0(U8Xml.XmlNode)
at System.Linq.Enumerable+WhereEnumerableIterator`1[[U8Xml.XmlNode, U8XmlParser, Version=1.6.1.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
Going to try and specifically keep the GC from cleaning up xmlDoc
public static XsdTypeBinder FromText(string content)
{
var xmlDoc = XmlParser.Parse(content);
var rootNode = xmlDoc.Root;
var parser = new XsdParser(rootNode);
var elements = parser.Parse();
GC.KeepAlive(xmlDoc); // <- new code
return new XsdTypeBinder(elements);
}
@simon-curtis Could you please share the entire code and the XML needed to reproduce this bug?
Turns out it was a GC issue but much higher up in my code. I was using a stream that was being disposed. Wrapping it in using (x) { //... }
fixed the issue
Describe the bug:
Intermittent bug when trying to get an attribute from a node while in an
IEnumerable<XmlNode>
fromXmlNodeDescendantList
Our code for reference:
Environment:
library version: 1.6.1 .NET version: .NET6 6.0.13 OS: Windows10
Steps to Reproduce:
call
node.TryFindAttribute(<string value>, out var attribute)
Expected behavior:
Return the attribute
Actual Behavior: