assertSame($version, $result['version']); $this->assertSame($upper, $result['upper']); $this->assertSame($lower, $result['lower']); } /** * The data provider for test_ip_in_range(). * * @return mixed[][] Returns an array of test cases. */ public function ip_in_range_provider(): array { $tests = [ ['192.168.11.2', '192.168.0.0/16', true], ['192.168.11.2', '192.168.64.1/16', true], ['192.168.11.2', '192.168.64.1/18', false], ['192.168.11.2', '192.168.11.0/20', true], ['127.0.0.1', '127.0.0.0/7', true], ['127.0.0.1', '127.0.0.0/8', true], ['127.0.0.1', '127.200.0.0/8', true], ['127.0.0.1', '127.200.0.0/9', false], ['127.0.0.1', '127.0.0.0/31', true], ['127.0.0.1', '127.0.0.0/32', false], ['127.0.0.1', '127.0.0.1/32', true], ['1111:2222:3333:4444:5555:6666:7777:8888', '1110::/12', true], ['1110:2222:3333:4444:5555:6666:7777:8888', '1110::/12', true], ['1100:2222:3333:4444:5555:6666:7777:8888', '1110::/12', false], ['1111:2222:3333:4444:5555:6666:7777:8888', '1111:2222:3300::/40', true], ['1111:2222:3333:4444:5555:6666:7777:8888', '1111:2222:3200::/40', false], ['1111:2222:3333:4444:5555:6666:7777:8888', '1111:2222:3333:4444:5555:6666:7777:8889/127', true], ['1111:2222:3333:4444:5555:6666:7777:8888', '1111:2222:3333:4444:5555:6666:7777:8889/128', false], ['1111:2222:3333:4444:5555:6666:7777:8889', '1111:2222:3333:4444:5555:6666:7777:8889/128', true], ['abcd:ef0a:bcde:f0ab:cdef:0abc:def0:abcd', 'abcd:ef0a:bcde:f0ab:cdef:0abc:def0:abcd/128', true], ['abcd:ef0a:bcde:f0ab:cdef:0abc:def0:abce', 'abcd:ef0a:bcde:f0ab:cdef:0abc:def0:abcd/128', false], ]; return $tests; } /** * Test ipInRange(). * * @dataProvider ip_in_range_provider * * @param string $ip The IP to test. * @param string $range The IP range to test against. * @param bool $expected The expected result from ipInRange(). * * @return void */ public function test_ip_in_range(string $ip, string $range, bool $expected): void { $result = Ip::ipInRange($ip, $range); $this->assertSame($expected, $result); } /** * Data provider for test_ip_matches(). * * @return mixed[][] Returns an array of test cases. */ public function ip_matches_provider(): array { // Tests for a CIDR range. $rangeTests = $this->ip_in_range_provider(); // Tests for an exact IP match. $exactTests = [ ['127.0.0.1', '127.0.0.1', true], ['127.0.0.1', '127.0.0.0', false], ['aaaa:bbbb:cccc:dddd:eeee::', 'aaaa:bbbb:cccc:dddd:eeee:0000:0000:0000', true], ['aaaa:bbbb:cccc:dddd:eeee:0000:0000:0000', 'aaaa:bbbb:cccc:dddd:eeee::', true], ['aaaa:bbbb:0000:0000:0000:0000:0000:0001', 'aaaa:bbbb::1', true], ['aaaa:bbbb::0001', 'aaaa:bbbb::1', true], ['aaaa:bbbb::0001', 'aaaa:bbbb::', false], ['::ffff:127.0.0.1', '127.0.0.1', false], ['::ffff:127.0.0.1', '::0:ffff:127.0.0.1', true], ]; return array_merge($rangeTests, $exactTests); } /** * Test ipMatches(). * * @dataProvider ip_matches_provider * * @param string $ip The IP to test. * @param string $ipOrRange The IP or IP range to test against. * @param bool $expected The expeced result from ipMatches(). * * @return void */ public function test_ip_matches(string $ip, string $ipOrRange, bool $expected): void { $result = Ip::ipMatches($ip, $ipOrRange); $this->assertSame($expected, $result); } /** * Data provider for proxyIsTrusted(). * * @return mixed[][] Returns an array of test cases. */ public function proxy_is_trusted_provider(): array { // The new default configuration value. $default = ['::1', 'fe80::/10', '127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']; // Adding some custom trusted proxies. $custom = array_merge($default, ['1.2.3.4', '1122::', '3.0.0.1/8', '1111:2222::/32']); $tests = [ // Empty configuration. ['', '127.0.0.1', false], // Configuration with an array of IPs/CIDRs. [$default, '127.0.0.1', true], [$default, '127.1.2.3', true], [$default, '10.1.2.3', true], [$default, '11.1.2.3', false], [$default, '172.16.0.1', true], [$default, '172.160.0.1', false], [$default, '172.31.255.255', true], [$default, '172.32.0.0', false], [$default, '172.200.0.0', false], [$default, '192.168.2.3', true], [$default, '192.169.1.2', false], [$default, '::1', true], [$default, '0000:0000:0000:0000:0000:0000:0000:0001', true], // With custom proxies set. [$custom, '127.0.0.1', true], [$custom, '1.2.3.4', true], [$custom, '3.0.1.2', true], [$custom, '1122::', true], [$custom, '1122:0000:0000:0000:0000:0000:0000:0000', true], [$custom, '1111:2223::', false], [$custom, '1111:2222::', true], [$custom, '1111:2222:3333::', true], [$custom, '1111:2222:3333::1', true], ]; return $tests; } /** * Test proxyIsTrusted(). * * @dataProvider proxy_is_trusted_provider * * @param string|string[] $config The value for $conf[trustedproxies]. * @param string $ip The proxy IP to test. * @param bool $expected The expected result from proxyIsTrusted(). */ public function test_proxy_is_trusted($config, string $ip, bool $expected): void { global $conf; $conf['trustedproxies'] = $config; $result = Ip::proxyIsTrusted($ip); $this->assertSame($expected, $result); } /** * Data provider for test_forwarded_for(). * * @return mixed[][] Returns an array of test cases. */ public function forwarded_for_provider(): array { // The new default configuration value. $default = ['::1', 'fe80::/10', '127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']; // Adding some custom trusted proxies. $custom = array_merge($default, ['1.2.3.4', '1122::', '3.0.0.1/8', '1111:2222::/32']); $tests = [ // Empty config value should always return empty array. [[], '', '127.0.0.1', []], [[], '127.0.0.1', '127.0.0.1', []], // The new default configuration. [$default, '', '127.0.0.1', []], [$default, '1.2.3.4', '127.0.0.1', ['1.2.3.4', '127.0.0.1']], [$default, '1.2.3.4', '192.168.1.1', ['1.2.3.4', '192.168.1.1']], [$default, '1.2.3.4,172.16.0.1', '192.168.1.1', ['1.2.3.4', '172.16.0.1', '192.168.1.1']], [$default, '1.2.3.4,172.16.0.1', '::1', ['1.2.3.4', '172.16.0.1', '::1']], [$default, '1.2.3.4,172.16.0.1', '::0001', ['1.2.3.4', '172.16.0.1', '::0001']], // Directly from an untrusted proxy. [$default, '', '127.0.0.1', []], [$default, '1.2.3.4', '11.22.33.44', []], [$default, '::1', '11.22.33.44', []], [$default, '::1', '::2', []], // From a trusted proxy, but via an untrusted proxy. [$default, '1.2.3.4,11.22.33.44,172.16.0.1', '192.168.1.1', []], [$default, '1.2.3.4,::2,172.16.0.1', '::1', []], // A custom configuration. [$custom, '', '127.0.0.1', []], [$custom, '1.2.3.4', '127.0.0.1', ['1.2.3.4', '127.0.0.1']], [$custom, '1.2.3.4', '192.168.1.1', ['1.2.3.4', '192.168.1.1']], [$custom, '1.2.3.4,172.16.0.1', '192.168.1.1', ['1.2.3.4', '172.16.0.1', '192.168.1.1']], [$custom, '1.2.3.4,172.16.0.1', '::1', ['1.2.3.4', '172.16.0.1', '::1']], [$custom, '1.2.3.4,172.16.0.1', '::0001', ['1.2.3.4', '172.16.0.1', '::0001']], // Directly from an untrusted proxy. [$custom, '', '127.0.0.1', []], [$custom, '1.2.3.4', '11.22.33.44', []], [$custom, '::1', '11.22.33.44', []], [$custom, '::1', '::2', []], // From a trusted proxy, but via an untrusted proxy. [$custom, '1.2.3.4,11.22.33.44,172.16.0.1', '192.168.1.1', []], [$custom, '1.2.3.4,::2,172.16.0.1', '::1', []], // Via a custom proxy. [$custom, '11.2.3.4,3.1.2.3,172.16.0.1', '192.168.1.1', ['11.2.3.4', '3.1.2.3', '172.16.0.1', '192.168.1.1']], [$custom, '11.2.3.4,1122::,172.16.0.1', '3.0.0.1', ['11.2.3.4', '1122::', '172.16.0.1', '3.0.0.1']], [$custom, '11.2.3.4,1122::,172.16.0.1', '1111:2222:3333::', ['11.2.3.4', '1122::', '172.16.0.1', '1111:2222:3333::']], ]; return $tests; } /** * Test forwardedFor(). * * @dataProvider forwarded_for_provider * * @param string|string[] $config The trustedproxies config value. * @param string $header The X-Forwarded-For header value. * @param string $remoteAddr The TCP/IP peer address. * @param array $expected The expected result from forwardedFor(). * * @return void */ public function test_forwarded_for($config, string $header, string $remoteAddr, array $expected): void { /* @var Input $INPUT */ global $INPUT, $conf; $conf['trustedproxies'] = $config; $INPUT->server->set('HTTP_X_FORWARDED_FOR', $header); $INPUT->server->set('REMOTE_ADDR', $remoteAddr); $result = Ip::forwardedFor(); $this->assertSame($expected, $result); } }