Skip to content

Fix validated part uri equality - #8

Open
anurag6569201 wants to merge 1 commit into
qa/agent-dotnet-runtime/pr-08-131806/basefrom
qa/agent-dotnet-runtime/pr-08-131806/head
Open

anurag6569201 wants to merge 1 commit into
qa/agent-dotnet-runtime/pr-08-131806/basefrom
qa/agent-dotnet-runtime/pr-08-131806/head

Conversation

@anurag6569201

Copy link
Copy Markdown

Fixes dotnet#129927
PR dotnet#118574 added object.Equals/GetHashCode overrides to ValidatedPartUri (which derives from System.Uri) to support case-insensitive part-name matching. This broke the inherited Uri equality contract: Equals became asymmetric against a plain System.Uri of the same value, and GetHashCode became inconsistent with System.Uri.GetHashCode(). Consumers mixing ValidatedPartUri with plain System.Uri in HashSet/Dictionary<Uri,_> (e.g. the Open XML SDK) got incorrect lookup results.

Revert the Equals(object?)/GetHashCode() overrides, restoring the original CA1067 suppression. ValidatedPartUri once again inherits Uri's value-equality, matching plain System.Uri semantics.
Keep the case-insensitive Compare()/IComparable/ IEquatable logic, which is what makes Package.cs's SortedList<ValidatedPartUri, PackagePart> lookups case-insensitive (fixing dotnet#112783 for that path) and is unaffected by this change.
Add PackUriHelper.ValidatedPartUriEqualityComparer, an internal IEqualityComparer providing case-insensitive equality/hashing, and use it explicitly in ZipPackage's content-type override dictionary. Without this, removing GetHashCode() would leave that Dictionary<ValidatedPartUri,_> with a hash/equals mismatch (case-insensitive Equals via IEquatable, case-sensitive hash via inherited Uri.GetHashCode()), silently dropping parts whose zip entry name casing differs from their [Content_Types].xml Override PartName.
Add regression tests covering the Uri equality contract and the content-type override case-insensitivity behavior.

Source merge-base: 45fb46d810550207fe12a2b02dabec25f47c71ad
Source head: 70b21a9be4c1fe06a92a107e8dc13c6408b7f2bb

@shipwright-agent

Copy link
Copy Markdown

⛔ Shipwright · Blocked

Recommendation: do not merge PR #8 · Tier T1
Checks: 0 total · 0 needing attention

Next step: resolve the blocking findings before merge.

Findings (3)

  • CRITICAL The new ValidatedPartUriEqualityComparer.GetHashCode uses StringComparer.Ordinal.GetHashCode on NormalizedPartUriString, while IEquatable<ValidatedPartUri>.Equals compares via Comp · src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs:899
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • CRITICAL Removing the ValidatedPartUri.Equals(object) and GetHashCode overrides changes the equality semantics of a type that is still used as a key in Dictionary<ValidatedPartUri, ContentT · src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs:654
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • HIGH The new comparer's GetHashCode uses StringComparer.Ordinal while its Equals delegates to IEquatable<ValidatedPartUri>.Equals, which uses CompareOrdinal on NormalizedPartUriString. · src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs:876
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

Fireworks usage: 9,074 input · 585 output · 9,659 total tokens · $0.0024 · 11s · 0 fix iteration(s)

Open the Shipwright check for full evidence and the audit bundle. Use /shipwright rerun to verify again.

{
if (ReferenceEquals(x, y))
return true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · CRITICAL

The new ValidatedPartUriEqualityComparer.GetHashCode uses StringComparer.Ordinal.GetHashCode on NormalizedPartUriString, while IEquatable<ValidatedPartUri>.Equals compares via Comp

Impact: The new ValidatedPartUriEqualityComparer.GetHashCode uses StringComparer.Ordinal.GetHashCode on NormalizedPartUriString, while IEquatable<ValidatedPartUri>.Equals compares via Compare() which now uses string.CompareOrdinal. If NormalizedPartUriString is not actually normalized to a canonical case (e.g., upper-cased) for all inputs, two instances that are equal under CompareOrdinal could produce different hash…

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant