[guest - Mon Aug 16 09:09:59 2004]:
Show quoted text> ...
The attached patch resolves all these issues.
Best regards,
Martin
diff -urdN DNS-ZoneParse-0.91-orig/lib/DNS/ZoneParse.pm DNS-ZoneParse-0.91/lib/DNS/ZoneParse.pm
--- DNS-ZoneParse-0.91-orig/lib/DNS/ZoneParse.pm 2003-08-03 16:28:24.000000000 +0200
+++ DNS-ZoneParse-0.91/lib/DNS/ZoneParse.pm 2004-08-17 14:24:26.000000000 +0200
@@ -152,7 +152,7 @@
sub _load_file {
- my ($self, $zonefile) = @_;
+ my ($self, $zonefile, $origin) = @_;
my $zone_contents;
if(ref($zonefile) eq "SCALAR") {
$zone_contents = $$zonefile;
@@ -165,73 +165,75 @@
croak qq[DNS::ZoneParse Could not open input file: "$zonefile":$!]
}
}
- if ($self->_parse( $zonefile, $zone_contents )) { return 1; }
+ if ($self->_parse( $zonefile, $zone_contents, $origin )) { return 1; }
}
sub _parse {
- my ($self, $zonefile, $contents) = @_;
+ my ($self, $zonefile, $contents, $origin) = @_;
$self->_initialize();
my $chars = qr/[a-z\-\.0-9]+/i;
$contents =~ /Database file ($chars)( dns)? for ($chars) zone/si;
- $dns_id{$self} = _massage({ ZoneFile => $1 || $zonefile, Origin => $3 });
+ $dns_id{$self} = _massage({ ZoneFile => $1 || $zonefile, Origin => $3 || $origin });
my $records = $self->_clean_records($contents);
my $valid_name = qr/[\@a-z_\-\.0-9\*]+/i;
my $valid_ip6 = qr/[\@a-z_\-\.0-9\*:]+/i;
- my $rr_class = qr/\b(?:in|hs|ch)\b/i;
- my $rr_types = qr/\b(?:ns|a|cname)\b/i;
+ my $rr_class = qr/\b(?:IN|HS|CH)\b/i;
+ my $rr_type = qr/\b(?:NS|A|CNAME)\b/i;
my $rr_ttl = qr/(?:\d+[wdhms]?)+/i;
- my $ttl_cls = qr/(?:($rr_ttl)\s+)?(?:\b($rr_class)\s+)?\s*/;
+ my $ttl_cls = qr/(?:($rr_ttl)\s)?(?:($rr_class)\s)?/;
_massage(); # reset last_name
foreach (@$records) {
- if (/^($valid_name)? \s* # host
- (?:($rr_ttl)\s+)? # ttl
- (?:\b($rr_class)\s+)?\s* # class
- ($rr_types) \s+ # record type
+ if (/^($valid_name|\s)? \s* # host
+ $ttl_cls # ttl & class
+ ($rr_type) \s # record type
($valid_name) # record data
/ix) {
my ($name, $ttl, $class, $type, $host) = ($1, $2, $3, $4, $5);
- if (!$class && defined $name && $name =~ /^$rr_class$/) {
- $class = uc $name;
- undef $name;
- }
my $dns_thing = uc $type eq 'NS' ? $dns_ns{$self}
: uc $type eq 'A' ? $dns_a{$self} : $dns_cname{$self};
push @$dns_thing,
_massage({name => $name, class=> $class,
host => $host, ttl => $ttl})
}
- elsif (/($valid_name)? \s* $ttl_cls AAAA \s+ ($valid_ip6)/)
- {
+ elsif (/^($valid_name|\s)? \s*
+ $ttl_cls
+ AAAA \s
+ ($valid_ip6)
+ /x) {
my ($name, $ttl, $class, $host) = ($1, $2, $3, $4);
- if (!$class && defined $name && $name =~ /^$rr_class$/) {
- $class = uc $name;
- undef $name;
- }
push @{$dns_a4{$self}},
_massage({name => $name, class=> $class,
host => $host, ttl => $ttl})
}
- elsif (/($valid_name)? \s* $ttl_cls MX \s+ (\d+) \s+ ($valid_name)/ix)
- {
+ elsif (/^($valid_name|\s)? \s*
+ $ttl_cls
+ MX \s
+ (\d+) \s
+ ($valid_name)
+ /ix) {
# host ttl class mx pri dest
my ($name, $ttl, $class, $pri, $host) = ($1, $2, $3, $4, $5);
- if (!$class && defined $name && $name =~ /^$rr_class$/) {
- $class = uc $name;
- undef $name;
- }
push @{$dns_mx{$self}},
_massage({ name => $name, priority => $pri,
host => $host, ttl => $ttl, class => $class})
}
- elsif (/($valid_name) \s+ $ttl_cls
- SOA \s+ ($valid_name) \s+ ($valid_name) \s*
- \(?\s* ($rr_ttl) \s+ ($rr_ttl) \s+ ($rr_ttl) \s+
- ($rr_ttl) \s+ ($rr_ttl) \s* \)? /ix)
- {
+ elsif (/^($valid_name) \s
+ $ttl_cls
+ SOA \s
+ ($valid_name) \s
+ ($valid_name) \s*
+ \(? \s*
+ ($rr_ttl) \s
+ ($rr_ttl) \s
+ ($rr_ttl) \s
+ ($rr_ttl) \s
+ ($rr_ttl) \s*
+ \)?
+ /ix) {
# SOA record
my $ttl = $dns_soa{$self}->{ttl} || $2 || '';
$dns_soa{$self} =
@@ -239,8 +241,11 @@
email =>$5, serial => $6, refresh=> $7,
retry=> $8, expire=> $9, minimumTTL => $10 });
}
- elsif (/(\d$valid_name+)\s+($rr_ttl)?\s*?($rr_class)?\s*?PTR\s+($valid_name)/i)
- {
+ elsif (/^($valid_name|\s) \s*
+ $ttl_cls
+ PTR \s
+ ($valid_name)
+ /ix) {
# PTR
push @{$dns_ptr{$self}},
_massage({ name => $1, class => $3, ttl => $2, host => $4 });
@@ -253,6 +258,9 @@
elsif (/\$TTL\s+($rr_ttl)/i) {
$dns_soa{$self}->{ttl} = $1;
}
+ else {
+ carp "Unparseable line\n $_\n";
+ }
}
return 1;
}
@@ -261,21 +269,23 @@
my $self = shift;
my ($zone) = shift;
- $zone =~ s<\;.{0,}$><>mg; # Remove comments
- $zone =~ s<^\s*?$><>mg; # Remove empty lines
- $zone =~ s!$/{2,}!$/!g; # Remove double carriage returns
+ $zone =~ s<\;.*$> <>mg; # Remove comments
+ $zone =~ s<^\s*$> <>mg; # Remove empty lines
+ $zone =~ s<$/+> <$/>g; # Remove multiple carriage returns
+ $zone =~ s<[ \t]+>< >g; # Collapse whitespace, turn TABs to spaces
# Concatenate everything split over multiple lines i.e. elements surrounded
# by parentheses can be split over multiple lines. See RFC 1035 section 5.1
$zone =~ s{(\([^\)]*?\))}{_concatenate($1)}egs;
- my @records = map {s/^\s+//g; $_} split (m|$/|, $zone);
+ # Split into multiple records, and kick out empty lines
+ my @records = grep !/^$/, split (m|$/|, $zone);
return \@records;
}
sub _concatenate {
my $text_in_parenth= shift;
- $text_in_parenth=~ s{$/}{}g;
+ $text_in_parenth=~ s{\s*$/\s*}{ }g;
return $text_in_parenth;
}
@@ -288,7 +298,7 @@
$record->{$_} = uc $record->{$_} if $_ eq 'class';
}
return $record unless defined $record->{name};
- if (length $record->{name}) {
+ if (length $record->{name} && $record->{name} ne ' ') {
$last_name = $record->{name};
} else {
$record->{name} = $last_name;
diff -urdN DNS-ZoneParse-0.91-orig/t/dns-zoneparse.t DNS-ZoneParse-0.91/t/dns-zoneparse.t
--- DNS-ZoneParse-0.91-orig/t/dns-zoneparse.t 2003-08-03 16:29:02.000000000 +0200
+++ DNS-ZoneParse-0.91/t/dns-zoneparse.t 2004-08-17 11:57:56.000000000 +0200
@@ -64,19 +64,22 @@
'ttl' => '', 'name' => 'www', 'class' => 'IN', 'host' => '10.0.0.2'
},
{
- 'ttl' => '', 'name' => 'www', 'class' => '', 'host' => '10.0.0.4'
+ 'ttl' => '43200', 'name' => 'www', 'class' => 'IN', 'host' => '10.0.0.3'
},
{
- 'ttl' => '', 'name' => 'foo', 'class' => 'IN', 'host' => '10.0.0.5'
+ 'ttl' => '', 'name' => 'www', 'class' => '', 'host' => '10.0.0.5'
+ },
+ {
+ 'ttl' => '', 'name' => 'foo', 'class' => 'IN', 'host' => '10.0.0.6'
},
{
- 'ttl' => '', 'name' => 'mini', 'class' => '', 'host' => '10.0.0.6'
+ 'ttl' => '', 'name' => 'mini', 'class' => '', 'host' => '10.0.0.7'
},
], 'A records parsed OK');
is_deeply($zf->ns, [
{
- 'ttl' => '',
+ 'ttl' => '43200',
'name' => '@',
'class' => 'IN',
'host' => 'ns0.dns-zoneparse-test.net.'
@@ -102,7 +105,7 @@
'ttl' => '',
'name' => 'www',
'class' => 'IN',
- 'host' => '10.0.0.3'
+ 'host' => '10.0.0.4'
},
], 'MX records parsed OK');
diff -urdN DNS-ZoneParse-0.91-orig/t/test-zone.db DNS-ZoneParse-0.91/t/test-zone.db
--- DNS-ZoneParse-0.91-orig/t/test-zone.db 2003-08-03 16:27:04.000000000 +0200
+++ DNS-ZoneParse-0.91/t/test-zone.db 2004-08-17 11:57:56.000000000 +0200
@@ -8,7 +8,7 @@
691200 ; expire
86400 ) ; minimum TTL
-@ IN NS ns0.dns-zoneparse-test.net.
+ 43200 IN NS ns0.dns-zoneparse-test.net.
@ IN NS ns1.dns-zoneparse-test.net.
@ IN A 127.0.0.1
@@ -18,10 +18,11 @@
mail IN A 127.0.0.1
www IN A 127.0.0.1
in a 10.0.0.2
- IN MX 10 10.0.0.3
- A 10.0.0.4
-foo IN A 10.0.0.5
-mini A 10.0.0.6
+ 43200 IN A 10.0.0.3
+ IN MX 10 10.0.0.4
+ A 10.0.0.5
+foo IN A 10.0.0.6
+mini A 10.0.0.7
icarus IN AAAA fe80::0260:83ff:fe7c:3a2a
soup IN TXT "This is a text message"
txta TXT "This is another text message"