File Coverage

lib/Sisimai/RFC791.pm
Criterion Covered Total %
statement 45 45 100.0
branch 24 26 92.3
condition 11 13 84.6
subroutine 5 5 100.0
pod 2 2 100.0
total 87 91 95.6


line stmt bran cond sub pod time code
1             package Sisimai::RFC791;
2 98     98   95976 use v5.26;
  98         350  
3 98     98   493 use strict;
  98         214  
  98         2773  
4 98     98   420 use warnings;
  98         162  
  98         53199  
5              
6             sub is_ipv4address {
7             # Returns 1 if the argument is an IPv4 address
8             # @param [String] argv1 IPv4 address like "192.0.2.25"
9             # @return [Bool] 1: is an IPv4 address
10             # @since v5.2.0
11 83     83 1 1050 my $class = shift;
12 83 50 50     255 my $argv0 = shift || return 0; return 0 if length $argv0 < 7;
  83         327  
13 83 100       284 my @octet = split(/[.]/, $argv0); return 0 if scalar @octet != 4;
  83         371  
14              
15 42         81 for my $e ( @octet ) {
16             # Check each octet is between 0 and 255
17 58 100       353 return 0 unless $e =~ /\A[0-9]{1,3}\z/;
18 22         37 my $v = int $e;
19 22 100 66     94 return 0 if $v < 0 || $v > 255;
20             }
21 5         30 return 1;
22             }
23              
24             sub find {
25             # Find an IPv4 address from the given string
26             # @param [String] argv1 String including an IPv4 address
27             # @return [Array] List of IPv4 addresses
28             # @since v5.0.0
29 10373     10373 1 353002 my $class = shift;
30 10373 100 100     27828 my $argv0 = shift || return undef; return [] if length $argv0 < 7;
  10372         22136  
31 10371         20080 my $ipv4a = [];
32              
33 10371         19649 for my $e ( "(", ")", "[", "]", "," ) {
34             # Rewrite: "mx.example.jp[192.0.2.1]" => "mx.example.jp 192.0.2.1"
35 51855 100       77854 my $p0 = index($argv0, $e); next if $p0 < 0;
  51855         97969  
36 11000         19175 substr($argv0, $p0, 1, " ");
37             }
38              
39 10371         78286 IP4A: for my $e ( split(" ", $argv0) ) {
40             # Find string including an IPv4 address
41 199470 100       339974 next if index($e, ".") == -1; # IPv4 address must include "." character
42              
43 30742 100 100     40644 my $lx = length $e; next if $lx < 7 || $lx > 17; # 0.0.0.0 = 7, [255.255.255.255] = 17
  30742         97462  
44 13662         19230 my $cu = 0; # Cursor for seeking each octet of an IPv4 address
45 13662         19471 my $as = ""; # ASCII Code of each character
46 13662         17856 my $eo = ""; # Buffer of each octet of IPv4 Address
47              
48 13662         23970 while( $cu < $lx ) {
49             # Check whether each character is a number or "." or not
50 52353         71851 $as = ord substr($e, $cu++, 1);
51 52353 100 100     132268 if( $as < 48 || $as > 57 ) {
52             # The character is not a number(0-9)
53 20857 100       43987 next IP4A if $as != 46; # The character is not "."
54 11189 100       31423 next if $eo eq ""; # The current buffer is empty
55 11153 50       21340 next IP4A if int $eo > 255; # The current buffer is greater than 255
56 11153         13292 $eo = "";
57 11153         19648 next;
58             }
59 31496         44727 $eo .= chr $as;
60 31496 100       68918 next IP4A if int $eo > 255;
61             }
62 3228         11211 push @$ipv4a, $e;
63             }
64 10371         66413 return $ipv4a;
65             }
66              
67             1;
68             __END__