Fix validated part uri equality - #8
anurag6569201 wants to merge 1 commit into
Conversation
Source PR: dotnet#131806 Source head: 70b21a9
⛔ Shipwright · BlockedRecommendation: do not merge PR #8 · Tier
Findings (3)
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 |
| { | ||
| if (ReferenceEquals(x, y)) | ||
| return true; | ||
|
|
There was a problem hiding this comment.
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.
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:
45fb46d810550207fe12a2b02dabec25f47c71adSource head:
70b21a9be4c1fe06a92a107e8dc13c6408b7f2bb