Re: Cause of undefined offset notice
| From: | Martijn van Duren | Date: | Fri, 17 Nov 2017 20:51:27 +0000 |
| Subject: | Re: Cause of undefined offset notice | ||
| References: | 1 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-326265@lists.php.net to get a copy of this message | ||
Most probably an IP-address with only 2 dots.
$ php -r 'list($a, $b, $c, $d) = explode(".", "127.0.0");'
PHP Notice: Undefined offset: 3 in Command line code on line 1
Martijn van Duren
On 11/17/17 21:42, Jennifer wrote:
> Hello,
>
> I have a script that compares a visitors IP address against a file of known bad addresses but
> I'm getting this notice:
>
> Notice: Undefined offset: 3 (line 26 below)
>
> Can anyone see what I've done wrong? Perhaps this sub was not written correctly to begin
> with?
>
> Thank you,
> Jenni
>
> -----------------------------------------------------------
>
> function validate_ip($ip_array, $cm) {
> $msg = '';
> if (isset($cm['bad_ip_message'])) {
> $msg = $cm['bad_ip_message'];
> }
> if (@strpos( $cm['remote_ip'], ':' ) !== false) { return false; } // Skip
> IPv6 addresses (?).
>
> if (!is_array($ip_array)) { return false; }
> foreach ($ip_array as $banned_ip) {
> $banned_ip = trim($banned_ip);
> if ($banned_ip[0] === '#' || $banned_ip === '') { continue; } // Skip
> comments and blank lines.
>
> if ( @strpos( $banned_ip, '/' ) === false ) {
> if (ip2long($banned_ip) === ip2long($cm['remote_ip'])) {
> ban_message($msg);
> }
> if (substr($banned_ip, -1) == '0') {
> $banned_ip .= '/24'; // Create a CIDR if IP ends in '0'.
> }
> }
> if ( @strpos( $banned_ip, '/' ) !== false ) {
> // Get the base and the bits from the CIDR.
> list($base, $bits) = explode('/', $banned_ip);
>
> // Now split it up into it's classes.
> list($a, $b, $c, $d) = explode('.', $base); // Notice: Undefined offset: 3
>
> // Now do some bit shifting/switching to convert to ints.
> $i = ($a << 24) + ($b << 16) + ($c << 8) + $d;
> $mask = $bits == 0 ? 0: (~0 << (32 - $bits));
>
> // Here's our lowest int.
> $low = $i & $mask;
>
> // Here's our highest int.
> $high = $i | (~$mask & 0xFFFFFFFF);
>
> // Now split up the IP we're checking against into classes.
> list($a, $b, $c, $d) = explode('.', $cm['remote_ip']);
>
> // Now convert the IP we're checking against to an int.
> $check = ($a << 24) + ($b << 16) + ($c << 8) + $d;
>
> // If the IP is within the range, including highest/lowest values,
> // then it's within the CIDR range.
> if ($check >= $low && $check <= $high) {
> ban_message($msg);
> }
> }
> }
> return;
> }
>