Skip to content

Commit

Permalink
Fixed a bug which caused calls to GetHashCode() on schema Element obj…
Browse files Browse the repository at this point in the history
…ects without explicitly defined ID attributes to throw a NullReferenceException. This fixes Null Element IDs Crashes JeffFerguson.Gepsio.Xsd.Element.GetHashCode() #57.
  • Loading branch information
JeffFerguson committed Dec 15, 2024
1 parent b017c22 commit c381813
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 58 deletions.
115 changes: 63 additions & 52 deletions JeffFerguson.Gepsio.Test/IssueTests/SingleMethodIssueTests.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;

using JeffFerguson.Gepsio.IoC;
using JeffFerguson.Gepsio.Xml.Implementation.SystemXml;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace JeffFerguson.Gepsio.Test.IssueTests
Expand Down Expand Up @@ -79,9 +73,9 @@ public void VerifyFixForIssue9()
{
var xbrlDoc = new XbrlDocument();
xbrlDoc.Load("https://www.sec.gov/Archives/edgar/data/1688568/000168856818000036/csc-20170331.xml");
foreach(var validationError in xbrlDoc.ValidationErrors)
foreach (var validationError in xbrlDoc.ValidationErrors)
{
if(validationError.Message.Contains("http://xbrl.sec.gov/dei/2014-01-31") == true)
if (validationError.Message.Contains("http://xbrl.sec.gov/dei/2014-01-31") == true)
{
Assert.Fail();
}
Expand Down Expand Up @@ -126,54 +120,54 @@ public void VerifyFixForIssue11()
}
}

/// <summary>
/// Ensure that decimal number parsing is culture independant.
/// For example french uses , (comma) as decimal separator.
/// </summary>
[TestMethod]
public void VerifyFixForIssue16()
{
try
{
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo( "fr" );
var xbrlDoc = new XbrlDocument( );
xbrlDoc.Load( "https://www.sec.gov/Archives/edgar/data/1688568/000168856818000036/csc-20170331.xml" );
}
catch(FormatException)
{
Assert.Fail( "Decimal number format should be culture independant." );
}
}
/// <summary>
/// Ensure that decimal number parsing is culture independant.
/// For example french uses , (comma) as decimal separator.
/// </summary>
[TestMethod]
public void VerifyFixForIssue16()
{
try
{
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("fr");
var xbrlDoc = new XbrlDocument();
xbrlDoc.Load("https://www.sec.gov/Archives/edgar/data/1688568/000168856818000036/csc-20170331.xml");
}
catch (FormatException)
{
Assert.Fail("Decimal number format should be culture independant.");
}
}

/// <summary>
/// No Support for xsd:import in Schema Handling.
/// As a consequence in ESRD taxonomy, label linkbases are not discovered.
/// </summary>
[TestMethod]
public void VerifyFixForIssue50()
{
var xbrlDoc = new XbrlDocument( );
xbrlDoc.Load( @"..\..\..\IssueTests\50\efrag-2026-12-31-en.xbrl" );
var xbrlSchema = xbrlDoc.XbrlFragments[0].Schemas[0];
/// <summary>
/// No Support for xsd:import in Schema Handling.
/// As a consequence in ESRD taxonomy, label linkbases are not discovered.
/// </summary>
[TestMethod]
public void VerifyFixForIssue50()
{
var xbrlDoc = new XbrlDocument();
xbrlDoc.Load(@"..\..\..\IssueTests\50\efrag-2026-12-31-en.xbrl");
var xbrlSchema = xbrlDoc.XbrlFragments[0].Schemas[0];

Assert.IsTrue( xbrlSchema.DefinitionLinkbases.Any() ); //definition linkbases are in main schema
Assert.IsTrue( xbrlSchema.LabelLinkbases.Any() ); //label linkbases are in imported schema
}
Assert.IsTrue(xbrlSchema.DefinitionLinkbases.Any()); //definition linkbases are in main schema
Assert.IsTrue(xbrlSchema.LabelLinkbases.Any()); //label linkbases are in imported schema
}

/// <summary>
/// Error parsing PresentationArc Order value when culture is french.
/// </summary>
[TestMethod]
public void VerifyFixForIssue52()
{
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo( "fr" );
var xbrlDoc = new XbrlDocument( );
xbrlDoc.Load( @"..\..\..\IssueTests\52\efrag-2026-12-31-en.xbrl" );
var nodes = xbrlDoc.XbrlFragments[0].GetPresentableFactTree( ).TopLevelNodes;
/// <summary>
/// Error parsing PresentationArc Order value when culture is french.
/// </summary>
[TestMethod]
public void VerifyFixForIssue52()
{
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("fr");
var xbrlDoc = new XbrlDocument();
xbrlDoc.Load(@"..\..\..\IssueTests\52\efrag-2026-12-31-en.xbrl");
var nodes = xbrlDoc.XbrlFragments[0].GetPresentableFactTree().TopLevelNodes;

Assert.AreEqual( nodes[0].ChildNodes[3].PresentationLinkbaseLocator.HrefResourceId, "esrs_UndertakingIsNotRequiredToDrawupFinancialStatements" );
Assert.AreEqual( nodes[0].ChildNodes[4].PresentationLinkbaseLocator.HrefResourceId, "esrs_DisclosureOfExtentToWhichSustainabilityStatementCoversUpstreamAndDownstreamValueChainExplanatory" );
}
Assert.AreEqual(nodes[0].ChildNodes[3].PresentationLinkbaseLocator.HrefResourceId, "esrs_UndertakingIsNotRequiredToDrawupFinancialStatements");
Assert.AreEqual(nodes[0].ChildNodes[4].PresentationLinkbaseLocator.HrefResourceId, "esrs_DisclosureOfExtentToWhichSustainabilityStatementCoversUpstreamAndDownstreamValueChainExplanatory");
}

/// <summary>
/// Ensure that the taxonomy at http://xbrl.fasb.org/us-gaap/2018/elts/us-gaap-2018-01-31.xsd
Expand Down Expand Up @@ -216,5 +210,22 @@ public async Task VerifyFixForIssue22Async()
Assert.Fail();
}
}

/// <summary>
/// Verify that GetHashCode() can be called on schema elements that lack defined ID attributes.
/// </summary>
/// <remarks>
/// The hash code returned is not important to the test. The test is simply in place so that the
/// GetHashCode() method can be called without a NullReferenceException being thrown.
/// </remarks>
[TestMethod]
public void VerifyFixForIssue57()
{
var xbrlDoc = new XbrlDocument();
xbrlDoc.Load("http://xbrlsite.com/US-GAAP/BasicExample/2010-09-30/abc-20101231.xml");
var firstFragment = xbrlDoc.XbrlFragments[0];
var elementWithoutDefinedId = firstFragment.Schemas.GetElement("explicitMember");
var hashCode = elementWithoutDefinedId.GetHashCode();
}
}
}
8 changes: 4 additions & 4 deletions JeffFerguson.Gepsio/Xsd/Element.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ internal Element(XbrlSchema Schema, ISchemaElement SchemaElement)
{
this.Schema = Schema;
thisSchemaElement = SchemaElement;
this.Id = SchemaElement.Id;
this.Name = SchemaElement.Name;
this.Default = string.IsNullOrEmpty(SchemaElement.Default) == false ? SchemaElement.Default : string.Empty;
this.Id = string.IsNullOrEmpty(SchemaElement.Id) ? string.Empty : SchemaElement.Id;
this.Name = string.IsNullOrEmpty(SchemaElement.Name) ? string.Empty : SchemaElement.Name;
this.Default = string.IsNullOrEmpty(SchemaElement.Default) ? string.Empty : SchemaElement.Default;
this.IsAbstract = SchemaElement.IsAbstract;
this.TypeName = SchemaElement.SchemaTypeName;
SetSubstitutionGroup(SchemaElement.SubstitutionGroup);
Expand Down Expand Up @@ -145,7 +145,7 @@ public override bool Equals(object obj)
/// </returns>
public override int GetHashCode()
{
return this.Id.GetHashCode();
return this.Name.GetHashCode();
}

//------------------------------------------------------------------------------------
Expand Down
3 changes: 1 addition & 2 deletions release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ The [Wiki](https://github.com/JeffFerguson/gepsio/wiki) area of [the Github repo
Thank you for your contributions!

# Design

- No changes from the previous release.

# Bug Fixes

- No changes from the previous release.
- Fixed a bug which caused calls to `GetHashCode()` on schema `Element` objects without explicitly defined `ID` attributes to throw a `NullReferenceException`. This fixes [Issue 57](https://github.com/JeffFerguson/gepsio/issues/57).

# Breaking Changes

Expand Down

0 comments on commit c381813

Please sign in to comment.