We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.
| 1 | <?php |
||
| 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) |
|
| 103 | |||
| 104 | 37 | protected function verifyAddress($address) |
|
| 105 | { |
||
| 106 | 37 | return (boolean) filter_var( |
|
| 107 | $address, |
||
| 108 | 37 | FILTER_VALIDATE_IP, |
|
| 109 | [ |
||
| 110 | 37 | 'flags' => $this->ipOptions, |
|
| 111 | ] |
||
| 112 | ); |
||
| 113 | } |
||
| 114 | |||
| 115 | 27 | protected function verifyNetwork($input) |
|
| 130 | |||
| 131 | 6 | protected function belongsToSubnet($input) |
|
| 132 | { |
||
| 133 | 6 | $range = $this->networkRange; |
|
| 139 | } |
||
| 140 |