Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -601,9 +601,7 @@ private static bool IsPartNameEmpty(string partName)
/// to reduce the parsing and number of allocations for Strings and Uris
/// we cache the results after parsing.
/// </summary>
#pragma warning disable CA1067 // Override Equals because it implements IEquatable<T>; not overriding to avoid possible regressions in code that's working
internal sealed class ValidatedPartUri : Uri, IComparable<ValidatedPartUri>, IEquatable<ValidatedPartUri>
#pragma warning restore CA1067
{
//------------------------------------------------------
//
Expand Down Expand Up @@ -653,6 +651,22 @@ bool IEquatable<ValidatedPartUri>.Equals(ValidatedPartUri? otherPartUri)

#endregion IEquatable Methods

#region Overrides
Comment thread
alinpahontu2912 marked this conversation as resolved.

public override bool Equals(object? obj)
{
if (obj is ValidatedPartUri other)
return Compare(other) == 0;
return false;
}

public override int GetHashCode()
{
return StringComparer.OrdinalIgnoreCase.GetHashCode(NormalizedPartUriString);
}

#endregion Overrides

#region Internal Properties

//------------------------------------------------------
Expand Down Expand Up @@ -841,7 +855,11 @@ private int Compare(ValidatedPartUri? otherPartUri)
return 1;

//Compare the normalized uri strings for the two part uris.
return string.CompareOrdinal(NormalizedPartUriString, otherPartUri.NormalizedPartUriString);
return string.Compare(
NormalizedPartUriString,
otherPartUri.NormalizedPartUriString,
StringComparison.OrdinalIgnoreCase
);
Comment thread
alinpahontu2912 marked this conversation as resolved.
}

//------------------------------------------------------
Expand Down
39 changes: 36 additions & 3 deletions src/libraries/System.IO.Packaging/tests/PartPieceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace System.IO.Packaging.Tests
public class PartPieceTests : FileCleanupTestBase
{
private delegate byte[] FileContentsGenerator(PartConstructionParameters pcp, int totalLength);
private record class PartConstructionParameters (string FullPath, bool CreateAsAtomic, bool CreateAsValidPieceSequence, bool UppercaseFileName, bool ShufflePieces, int[] PieceLengths, FileContentsGenerator PieceGenerator)
private record class PartConstructionParameters(string FullPath, bool CreateAsAtomic, bool CreateAsValidPieceSequence, bool UppercaseFileName, bool ShufflePieces, int[] PieceLengths, FileContentsGenerator PieceGenerator)
{ }

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
Expand Down Expand Up @@ -85,7 +85,7 @@ private byte[] GenerateSequentialBytes(PartConstructionParameters pcp, int total
{
var bytes = new byte[totalLength];

for(int i = 0; i < totalLength; i++)
for (int i = 0; i < totalLength; i++)
{
bytes[i] = (byte)(i % 255);
}
Expand Down Expand Up @@ -209,7 +209,7 @@ public void InvalidPartPiecesAreNotParsable(string partPieceName)

Assert.NotNull(s_ZipPackagePartPieceType);
Assert.NotNull(s_TryParseZipPackagePartPiece);
Assert.False((bool)s_TryParseZipPackagePartPiece.Invoke(null, [ partPieceEntry, null ]));
Assert.False((bool)s_TryParseZipPackagePartPiece.Invoke(null, [partPieceEntry, null]));
}

[Theory]
Expand Down Expand Up @@ -326,6 +326,39 @@ public void UppercaseContentTypePartPieceSequenceIsFound()
Assert.NotEmpty(zipPackage.GetParts());
}

[Fact]
public void PartNamesAreCaseInsensitive()
{
using var ms = new MemoryStream();

using (var zipPackage = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite))
{
zipPackage.CreatePart(new Uri("/part", UriKind.Relative), "text/plain");
}
ms.Position = 0;
using (var zipPackage = Package.Open(ms, FileMode.Open, FileAccess.Read))
{
var lowerPart = zipPackage.GetPart(new Uri("/part", UriKind.Relative));
var upperPart = zipPackage.GetPart(new Uri("/PART", UriKind.Relative));

Assert.Same(lowerPart, upperPart);
Assert.Equal(lowerPart.Uri, upperPart.Uri);
Assert.Equal(lowerPart.ContentType, upperPart.ContentType);
}
}

[Fact]
public void DuplicatePartsDifferingOnlyByCaseAreNotAllowed()
{
using var ms = new MemoryStream();
using (var zipPackage = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite))
{
zipPackage.CreatePart(new Uri("/part", UriKind.Relative), "text/plain");
Assert.Throws<InvalidOperationException>(() =>
zipPackage.CreatePart(new Uri("/PART", UriKind.Relative), "text/plain"));
}
}

[Fact]
public void CanCreateAtomicPart()
{
Expand Down