Skip to content

Commit 7b04ecf

Browse files
authored
Fix IPNetwork.Contains behavior for prefixes which are not at start of subnet range (#31573)
1 parent 5de9b7d commit 7b04ecf

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

src/Middleware/HttpOverrides/src/IPNetwork.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
45
using System.Net;
6+
using System.Net.Sockets;
57

68
namespace Microsoft.AspNetCore.HttpOverrides
79
{
@@ -17,6 +19,8 @@ public class IPNetwork
1719
/// <param name="prefixLength">The prefix length.</param>
1820
public IPNetwork(IPAddress prefix, int prefixLength)
1921
{
22+
CheckPrefixLengthRange(prefix, prefixLength);
23+
2024
Prefix = prefix;
2125
PrefixLength = prefixLength;
2226
PrefixBytes = Prefix.GetAddressBytes();
@@ -31,7 +35,7 @@ public IPNetwork(IPAddress prefix, int prefixLength)
3135
private byte[] PrefixBytes { get; }
3236

3337
/// <summary>
34-
/// The CIDR notation of the subnet mask
38+
/// The CIDR notation of the subnet mask
3539
/// </summary>
3640
public int PrefixLength { get; }
3741

@@ -52,7 +56,7 @@ public bool Contains(IPAddress address)
5256
var addressBytes = address.GetAddressBytes();
5357
for (int i = 0; i < PrefixBytes.Length && Mask[i] != 0; i++)
5458
{
55-
if (PrefixBytes[i] != (addressBytes[i] & Mask[i]))
59+
if ((PrefixBytes[i] & Mask[i]) != (addressBytes[i] & Mask[i]))
5660
{
5761
return false;
5862
}
@@ -79,5 +83,23 @@ private byte[] CreateMask()
7983

8084
return mask;
8185
}
86+
87+
private static void CheckPrefixLengthRange(IPAddress prefix, int prefixLength)
88+
{
89+
if (prefixLength < 0)
90+
{
91+
throw new ArgumentOutOfRangeException(nameof(prefixLength));
92+
}
93+
94+
if (prefix.AddressFamily == AddressFamily.InterNetwork && prefixLength > 32)
95+
{
96+
throw new ArgumentOutOfRangeException(nameof(prefixLength));
97+
}
98+
99+
if (prefix.AddressFamily == AddressFamily.InterNetworkV6 && prefixLength > 128)
100+
{
101+
throw new ArgumentOutOfRangeException(nameof(prefixLength));
102+
}
103+
}
82104
}
83105
}

src/Middleware/HttpOverrides/test/IPNetworkTest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ public class IPNetworkTest
1212
[InlineData("174.0.0.0", 7, "175.1.1.10")]
1313
[InlineData("10.174.0.0", 15, "10.175.1.10")]
1414
[InlineData("10.168.0.0", 14, "10.171.1.10")]
15+
[InlineData("192.168.0.1", 31, "192.168.0.0")]
16+
[InlineData("192.168.0.1", 31, "192.168.0.1")]
17+
[InlineData("192.168.0.1", 32, "192.168.0.1")]
18+
[InlineData("192.168.1.1", 0, "0.0.0.0")]
19+
[InlineData("192.168.1.1", 0, "255.255.255.255")]
20+
[InlineData("2001:db8:3c4d::", 127, "2001:db8:3c4d::1")]
21+
[InlineData("2001:db8:3c4d::1", 128, "2001:db8:3c4d::1")]
22+
[InlineData("2001:db8:3c4d::1", 0, "::")]
23+
[InlineData("2001:db8:3c4d::1", 0, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]
1524
public void Contains_Positive(string prefixText, int length, string addressText)
1625
{
1726
var network = new IPNetwork(IPAddress.Parse(prefixText), length);
@@ -23,6 +32,9 @@ public void Contains_Positive(string prefixText, int length, string addressText)
2332
[InlineData("174.0.0.0", 7, "173.1.1.10")]
2433
[InlineData("10.174.0.0", 15, "10.173.1.10")]
2534
[InlineData("10.168.0.0", 14, "10.172.1.10")]
35+
[InlineData("192.168.0.1", 31, "192.168.0.2")]
36+
[InlineData("192.168.0.1", 32, "192.168.0.0")]
37+
[InlineData("2001:db8:3c4d::", 127, "2001:db8:3c4d::2")]
2638
public void Contains_Negative(string prefixText, int length, string addressText)
2739
{
2840
var network = new IPNetwork(IPAddress.Parse(prefixText), length);

0 commit comments

Comments
 (0)