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
22 changes: 19 additions & 3 deletions csharp/PhoneNumbers.Test/TestMetadataFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -887,10 +887,26 @@ public void TestIntegrityOfFieldSets()
}

[Fact]
public void TestEquals_WhenNull_ReturnsFalse()
public void TestEqualsRejectsNullAndForeignTypesAndAcceptsSameBlacklist()
{
var result = new MetadataFilter(new Dictionary<string, SortedSet<string>>()).Equals(null);
Assert.False(result);
var filter = new MetadataFilter(new Dictionary<string, SortedSet<string>>());

// Object.Equals must answer false for a null reference rather than throwing. The null is
// held in a variable so the call is a real reference comparison at run time rather than
// a literal argument, which reads as a compile-time constant comparison.
object? nullReference = null;
Assert.False(filter.Equals(nullReference));

// ... and false for an object that is not a MetadataFilter at all. Held in an object
// local for the same reason: passing the string literal straight in is a comparison
// between statically incomparable types, which is a real smell everywhere except here.
object foreignObject = "not a MetadataFilter";
Assert.False(filter.Equals(foreignObject));

// Equality is by blacklist contents, so a separately built empty filter is equal, and a
// filter carrying a non-empty blacklist is not.
Assert.True(filter.Equals(MetadataFilter.EmptyFilter()));
Assert.False(filter.Equals(MetadataFilter.ForLiteBuild()));
}

[Fact]
Expand Down
19 changes: 19 additions & 0 deletions csharp/PhoneNumbers.Test/TestPhoneNumberUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,25 @@ public void TestMaybeStripNationalPrefix()
Assert.Equal(transformedNumber, numberToStrip.ToString());
}

[Fact]
public void TestMaybeStripNationalPrefixLeavesEmptyNumberAlone()
{
var metadata = new PhoneMetadata.Builder()
.SetNationalPrefixForParsing("34")
.SetGeneralDesc(new PhoneNumberDesc.Builder().SetNationalNumberPattern("\\d{4,8}").Build())
.BuildPartial();
// A zero-length number has no national prefix to strip, and asking must not throw even
// though there is nothing to turn into a string.
var numberToStrip = new StringBuilder();
Assert.False(phoneUtil.MaybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata, null));
Assert.Equal("", numberToStrip.ToString());

// Same for a carrier code being requested.
var carrierCode = new StringBuilder();
Assert.False(phoneUtil.MaybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata, carrierCode));
Assert.Equal("", carrierCode.ToString());
}

[Fact]
public void TestMaybeStripInternationalPrefix()
{
Expand Down
24 changes: 20 additions & 4 deletions csharp/PhoneNumbers/PhoneNumberUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2604,14 +2604,30 @@ public bool MaybeStripNationalPrefixAndCarrierCode(StringBuilder number, PhoneMe
internal bool MaybeStripNationalPrefixAndCarrierCode(StringBuilder number, string numberString, PhoneMetadata metadata, bool getCarrier, out string carrierCode)
{
carrierCode = null;
var numberLength = numberString?.Length ?? number?.Length ?? 0;
if (numberLength == 0 || !metadata.HasNationalPrefixForParsing)
if (!metadata.HasNationalPrefixForParsing)
{
return false;
}
// Callers supply either form of the number: the ones that already hold a string pass it
// so the StringBuilder need not be materialised, while the public overload passes only
// the StringBuilder. Branch on which one was supplied rather than folding both into a
// single length, so the ToString() below is reached only when the StringBuilder is the
// form that is present.
if (numberString is null)
{
// Early return for numbers of zero length.
if (number is null || number.Length == 0)
{
return false;
}
// Attempt to parse the first digits as a national prefix.
numberString = number.ToString();
}
else if (numberString.Length == 0)
{
// Early return for numbers of zero length.
return false;
}
// Attempt to parse the first digits as a national prefix.
numberString ??= number.ToString();

// Whether the groups are needed at all is known before matching: only a transform rule or
// a requested carrier code reads them. Without either, the length of the prefix is the
Expand Down