Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Completed
Pull Request — 1.1 (#1169)
by Henrique
02:59
created

Ip::parseRange()   B

Complexity

Conditions 11
Paths 11

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 11.0245

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 16
cts 17
cp 0.9412
rs 7.3166
c 0
b 0
f 0
cc 11
nc 11
nop 1
crap 11.0245

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of Respect/Validation.
5
 *
6
 * (c) Alexandre Gomes Gaigalas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the "LICENSE.md"
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Respect\Validation\Rules;
13
14
use Respect\Validation\Exceptions\ComponentException;
15
16
class Ip extends AbstractRule
17
{
18
    public $ipOptions;
19
20
    public $networkRange;
21
22 40
    public function __construct($ipOptions = null)
23
    {
24 40
        if (is_int($ipOptions)) {
25 1
            $this->ipOptions = $ipOptions;
26
27 1
            return;
28
        }
29
30 39
        $this->networkRange = $this->parseRange($ipOptions);
31 32
    }
32
33 39
    protected function parseRange($input)
34
    {
35 39
        if ($input === null || $input == '*' || $input == '*.*.*.*'
36 39
            || $input == '0.0.0.0-255.255.255.255') {
37 9
            return;
38
        }
39
40 30
        $range = ['min' => null, 'max' => null, 'mask' => null];
41
42 30
        if (strpos($input, '-') !== false) {
43 8
            list($range['min'], $range['max']) = explode('-', $input);
44 22
        } elseif (strpos($input, '*') !== false) {
45 11
            $this->parseRangeUsingWildcards($input, $range);
46 11
        } elseif (strpos($input, '/') !== false) {
47 9
            $this->parseRangeUsingCidr($input, $range);
48
        } else {
49 2
            throw new ComponentException('Invalid network range');
50
        }
51
52 25
        if (!$this->verifyAddress($range['min'])) {
53
            throw new ComponentException('Invalid network range');
54
        }
55
56 25
        if (isset($range['max']) && !$this->verifyAddress($range['max'])) {
57 2
            throw new ComponentException('Invalid network range');
58
        }
59
60 23
        return $range;
61
    }
62
63 20
    protected function fillAddress(&$input, $char = '*')
64
    {
65 20
        while (substr_count($input, '.') < 3) {
66 5
            $input .= '.'.$char;
67
        }
68 20
    }
69
70 11
    protected function parseRangeUsingWildcards($input, &$range)
71
    {
72 11
        $this->fillAddress($input);
73
74 11
        $range['min'] = strtr($input, '*', '0');
75 11
        $range['max'] = str_replace('*', '255', $input);
76 11
    }
77
78 9
    protected function parseRangeUsingCidr($input, &$range)
79
    {
80 9
        $input = explode('/', $input);
81 9
        $this->fillAddress($input[0], '0');
82
83 9
        $range['min'] = $input[0];
84 9
        $isAddressMask = strpos($input[1], '.') !== false;
85
86 9
        if ($isAddressMask && $this->verifyAddress($input[1])) {
87 2
            $range['mask'] = sprintf('%032b', ip2long($input[1]));
88
89 2
            return;
90
        }
91
92 7
        if ($isAddressMask || $input[1] < 8 || $input[1] > 30) {
93 3
            throw new ComponentException('Invalid network mask');
94
        }
95
96 4
        $range['mask'] = sprintf('%032b', ip2long(long2ip(~(pow(2, (32 - $input[1])) - 1))));
97 4
    }
98
99 33
    public function validate($input)
100
    {
101 33
        return $this->verifyAddress($input) && $this->verifyNetwork($input);
102
    }
103
104 37
    protected function verifyAddress($address)
105
    {
106 37
        return (boolean) filter_var(
107 37
            $address,
108 37
            FILTER_VALIDATE_IP,
109
            [
110 37
                'flags' => $this->ipOptions,
111
            ]
112
        );
113
    }
114
115 27
    protected function verifyNetwork($input)
116
    {
117 27
        if ($this->networkRange === null) {
118 4
            return true;
119
        }
120
121 23
        if (isset($this->networkRange['mask'])) {
122 6
            return $this->belongsToSubnet($input);
123
        }
124
125 17
        $input = sprintf('%u', ip2long($input));
126
127 17
        return bccomp($input, sprintf('%u', ip2long($this->networkRange['min']))) >= 0
128 17
               && bccomp($input, sprintf('%u', ip2long($this->networkRange['max']))) <= 0;
129
    }
130
131 6
    protected function belongsToSubnet($input)
132
    {
133 6
        $range = $this->networkRange;
134 6
        $min = sprintf('%032b', ip2long($range['min']));
135 6
        $input = sprintf('%032b', ip2long($input));
136
137 6
        return ($input & $range['mask']) === ($min & $range['mask']);
138
    }
139
}
140