Bug#1147101: trixie-pu: package libnet-dns-perl/1.57-0+deb13u1

Salvatore Bonaccorso carnil at debian.org
Mon Sep 7 16:58:11 BST 2026


Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: libnet-dns-perl at packages.debian.org, team at security.debian.org, debian-perl at lists.debian.org, gregoa at debian.org, carnil at debian.org
Control: affects -1 + src:libnet-dns-perl
User: release.debian.org at packages.debian.org
Usertags: pu

Dear Stable Release Managers

This is late for 13.7, but please consider it for 13.8.

libnet-dns-perl is affected by CVE-2026-81928, an unbound recursion
when re-encoding message with misplaced TSIG, which may result in
denial of service. We classified it as no-dsa, but it would be good to
have it fixed in trixie as well.

I opted here again to import the new upstream version, which
additionally contains:

- Resync with IANA DNS parameters registry.
- EDNS: Add support for MQTYPE-QUERY option.
- UNIX resolver can fail in taint mode

I already followed upstream recommendatation for the previous import,
which was released as DSA, so we had a bump from 1.50-1 in trixie to
1.56-0+deb13u1 and so now followed by 1.57-0+deb13u1.

Attached is only the debdiff beween the last security update and the
1.57-0+deb13u1 one.

Regards,
Salvatore
-------------- next part --------------
diff -Nru libnet-dns-perl-1.56/Changes libnet-dns-perl-1.57/Changes
--- libnet-dns-perl-1.56/Changes	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/Changes	2026-09-01 13:38:07.000000000 +0200
@@ -1,16 +1,30 @@
-$Id: Changes 2058 2026-07-17 10:09:31Z willem $                       -*-text-*-
+$Id: Changes 2061 2026-09-01 11:37:52Z willem $                       -*-text-*-
 
 
-**** 1.56 Jul 18, 2027
+**** 1.57 Sep 1, 2026
+
+	Resync with IANA DNS parameters registry.
+	EDNS: Add support for MQTYPE-QUERY option.
+
+Fix rt.cpan.org #181125
+	Unbounded recursion when re-encoding message with misplaced TSIG
+
+Fix rt.cpan.org #180773
+	UNIX resolver can fail in taint mode
+
+
+**** 1.56 Jul 18, 2026
 
 Fix rt.cpan.org #180088
 	Documentation issue for Net::DNS::RR::RRSIG::verify()
 
 Fix rt.cpan.org #179946
 	Denial of Service via long DNS compression chains
+	[CVE-2026-64194]
 
 Fix rt.cpan.org #179945
 	Remote code injection via EDNS EXTENDED ERROR
+	[CVE-2026-64193]
 
 Fix rt.cpan.org #179692/#176900
 	UNIX.pm: Unreachable code warning using Apache/mod_perl
diff -Nru libnet-dns-perl-1.56/META.json libnet-dns-perl-1.57/META.json
--- libnet-dns-perl-1.56/META.json	2026-07-17 12:10:11.000000000 +0200
+++ libnet-dns-perl-1.57/META.json	2026-09-01 14:09:56.000000000 +0200
@@ -6,7 +6,7 @@
       "Michael Fuhr"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010",
+   "generated_by" : "ExtUtils::MakeMaker version 7.78, CPAN::Meta::Converter version 2.150015",
    "license" : [
       "mit"
    ],
@@ -79,6 +79,6 @@
       }
    },
    "release_status" : "stable",
-   "version" : "1.56",
-   "x_serialization_backend" : "JSON::PP version 4.16"
+   "version" : "1.57",
+   "x_serialization_backend" : "JSON::PP version 4.18"
 }
diff -Nru libnet-dns-perl-1.56/META.yml libnet-dns-perl-1.57/META.yml
--- libnet-dns-perl-1.56/META.yml	2026-07-17 12:10:11.000000000 +0200
+++ libnet-dns-perl-1.57/META.yml	2026-09-01 14:09:56.000000000 +0200
@@ -18,7 +18,7 @@
   IO::File: '1.14'
   IO::Socket::IP: '0.38'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010'
+generated_by: 'ExtUtils::MakeMaker version 7.78, CPAN::Meta::Converter version 2.150015'
 license: mit
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -55,5 +55,5 @@
   perl: '5.008009'
   strict: '1.03'
   warnings: '1.0501'
-version: '1.56'
-x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
+version: '1.57'
+x_serialization_backend: 'CPAN::Meta::YAML version 0.020'
diff -Nru libnet-dns-perl-1.56/debian/changelog libnet-dns-perl-1.57/debian/changelog
--- libnet-dns-perl-1.56/debian/changelog	2026-08-21 19:24:30.000000000 +0200
+++ libnet-dns-perl-1.57/debian/changelog	2026-09-05 16:32:19.000000000 +0200
@@ -1,3 +1,12 @@
+libnet-dns-perl (1.57-0+deb13u1) trixie; urgency=medium
+
+  * Team upload.
+  * Import upstream version 1.57.
+    - Unbounded recursion when re-encoding message with misplaced TSIG
+      (CVE-2026-81928)
+
+ -- Salvatore Bonaccorso <carnil at debian.org>  Sat, 05 Sep 2026 16:32:19 +0200
+
 libnet-dns-perl (1.56-0+deb13u1) trixie-security; urgency=high
 
   * Team upload.
diff -Nru libnet-dns-perl-1.56/lib/Net/DNS/Parameters.pm libnet-dns-perl-1.57/lib/Net/DNS/Parameters.pm
--- libnet-dns-perl-1.56/lib/Net/DNS/Parameters.pm	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/lib/Net/DNS/Parameters.pm	2026-09-01 13:38:07.000000000 +0200
@@ -3,13 +3,13 @@
 ################################################
 ##
 ##	Domain Name System (DNS) Parameters
-##	(last updated 2026-07-06)
+##	(last updated 2026-08-24)
 ##
 ################################################
 
 use strict;
 use warnings;
-our $VERSION = (qw$Id: Parameters.pm 2054 2026-07-10 09:37:11Z willem $)[2];
+our $VERSION = (qw$Id: Parameters.pm 2059 2026-08-28 10:04:18Z willem $)[2];
 
 use integer;
 use Carp;
@@ -121,6 +121,8 @@
 	DSYNC	   => 66,					# RFC9859
 	HHIT	   => 67,					# RFC9886
 	BRID	   => 68,					# RFC9886
+	UNECE	   => 69,					# draft-woodcock-faltstrom-external-registry-rrtypes-00
+	ISO	   => 70,					# draft-woodcock-faltstrom-external-registry-rrtypes-00
 	SPF	   => 99,					# RFC7208
 	UINFO	   => 100,					# IANA-Reserved
 	UID	   => 101,					# IANA-Reserved
@@ -221,12 +223,13 @@
 	'SERVER-TAG'		  => 17,			# draft-bellis-dnsop-edns-tags-01
 	'REPORT-CHANNEL'	  => 18,			# RFC9567
 	ZONEVERSION		  => 19,			# RFC9660
-	'MQTYPE-QUERY'		  => 20,			# RFC-ietf-dnssd-multi-qtypes-14
-	'MQTYPE-RESPONSE'	  => 21,			# RFC-ietf-dnssd-multi-qtypes-14
+	'MQTYPE-QUERY'		  => 20,			# RFC10029
+	'MQTYPE-RESPONSE'	  => 21,			# RFC10029
 	'EDE-EXTRA-TEXT-LANGUAGE' => 22,			# draft-muks-dns-filtering-05
 	'FILTERING-CONTACT'	  => 23,			# draft-muks-dns-filtering-05
 	'FILTERING-ORGANIZATION'  => 24,			# draft-muks-dns-filtering-05
 	'FILTERING-DB'		  => 25,			# draft-muks-dns-filtering-05
+	'STRUCTURED-ERROR'	  => 26,			# RFC-ietf-dnsop-structured-dns-error-27
 	'UMBRELLA-IDENT' => 20292,				# https://developer.cisco.com/docs/cloud-security/#!integrating-network-devic
 	DEVICEID	 => 26946,				# https://developer.cisco.com/docs/cloud-security/#!network-devices-getting-s
 	);
@@ -252,6 +255,7 @@
 my @ednsflagbyname = (
 	DO => 0x8000,						# RFC4035 RFC3225 RFC6840
 	CO => 0x4000,						# RFC9824
+	DE => 0x2000,						# draft-ietf-dnsop-delext-08
 	);
 push @ednsflagbyname, map { /^\d/ ? $_ : lc($_) } @ednsflagbyname;
 our %ednsflagbyname = @ednsflagbyname;
@@ -309,6 +313,7 @@
 	32 => 'Over Quota',					# draft-muks-dns-ede-rate-limited-02
 	33 => 'Negative Trust Anchor',				# draft-farrokhi-dnsop-ede-nta-00
 	34 => 'New Delegation Only',				# draft-ietf-deleg-10
+	35 => 'Blocked by Upstream DNS Server',			# RFC-ietf-dnsop-structured-dns-error-27
 	);
 our %dnserrorbyval = @dnserrorbyval;
 
diff -Nru libnet-dns-perl-1.56/lib/Net/DNS/RR/DNSKEY.pm libnet-dns-perl-1.57/lib/Net/DNS/RR/DNSKEY.pm
--- libnet-dns-perl-1.56/lib/Net/DNS/RR/DNSKEY.pm	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/lib/Net/DNS/RR/DNSKEY.pm	2026-09-01 13:38:07.000000000 +0200
@@ -2,7 +2,7 @@
 
 use strict;
 use warnings;
-our $VERSION = (qw$Id: DNSKEY.pm 2042 2025-12-24 10:23:11Z willem $)[2];
+our $VERSION = (qw$Id: DNSKEY.pm 2059 2026-08-28 10:04:18Z willem $)[2];
 
 use base qw(Net::DNS::RR);
 
@@ -249,6 +249,7 @@
 		'ED25519'	     => 15,			# [RFC8080]
 		'ED448'		     => 16,			# [RFC8080]
 		'SM2SM3'	     => 17,			# [RFC9563]
+		'MLDSA44'	     => 18,			# [draft-westerbaan-dnssec-mldsa]
 		'ECC-GOST12'	     => 23,			# [RFC9558]
 
 		'INDIRECT'   => 252,				# [RFC4034]
diff -Nru libnet-dns-perl-1.56/lib/Net/DNS/RR/DS.pm libnet-dns-perl-1.57/lib/Net/DNS/RR/DS.pm
--- libnet-dns-perl-1.56/lib/Net/DNS/RR/DS.pm	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/lib/Net/DNS/RR/DS.pm	2026-09-01 13:38:07.000000000 +0200
@@ -2,7 +2,7 @@
 
 use strict;
 use warnings;
-our $VERSION = (qw$Id: DS.pm 2042 2025-12-24 10:23:11Z willem $)[2];
+our $VERSION = (qw$Id: DS.pm 2059 2026-08-28 10:04:18Z willem $)[2];
 
 use base qw(Net::DNS::RR);
 
@@ -222,6 +222,7 @@
 		'ED25519'	     => 15,			# [RFC8080]
 		'ED448'		     => 16,			# [RFC8080]
 		'SM2SM3'	     => 17,			# [RFC9563]
+		'MLDSA44'	     => 18,			# [draft-westerbaan-dnssec-mldsa]
 		'ECC-GOST12'	     => 23,			# [RFC9558]
 
 		'INDIRECT'   => 252,				# [RFC4034]
diff -Nru libnet-dns-perl-1.56/lib/Net/DNS/RR/OPT.pm libnet-dns-perl-1.57/lib/Net/DNS/RR/OPT.pm
--- libnet-dns-perl-1.56/lib/Net/DNS/RR/OPT.pm	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/lib/Net/DNS/RR/OPT.pm	2026-09-01 13:38:07.000000000 +0200
@@ -2,7 +2,7 @@
 
 use strict;
 use warnings;
-our $VERSION = (qw$Id: OPT.pm 2054 2026-07-10 09:37:11Z willem $)[2];
+our $VERSION = (qw$Id: OPT.pm 2059 2026-08-28 10:04:18Z willem $)[2];
 
 use base qw(Net::DNS::RR);
 
@@ -16,7 +16,7 @@
 use integer;
 
 use Carp;
-use Net::DNS::Parameters qw(:rcode :ednsoption);
+use Net::DNS::Parameters qw(:ednsoption);
 
 use constant UTIL => scalar eval { require Scalar::Util; Scalar::Util->can('isdual') };
 
@@ -204,7 +204,7 @@
 		my @value;
 		if ( length $value ) {
 			@value = eval { $package->_decompose($value) } if $structured;
-			@value = {BASE16 => unpack 'H*', $value} unless scalar @value;
+			@value = {BASE16 => pack 'U0a*', unpack 'H*', $value} unless scalar @value;
 			warn $@ if $@;
 		} else {
 			@value = $structured ? {'OPTION-LENGTH' => 0} : '';
@@ -265,20 +265,20 @@
 
 	if ( ref($value) eq 'HASH' ) {
 		my @tags = sort keys %$value;
-		my $tail = pop @tags;
 		for ( $$value{BASE16} ) { $_ = pack( 'U0a*', $_ ) if defined }	  # mark as UTF-8
-		my @body = map { my @x = ( qq("$_":), _JSONify( $$value{$_} ) ); $x[-1] .= ','; @x } @tags;
-		push @body, ( qq("$tail":), _JSONify( $$value{$tail} ) );
-		$body[0] = '{' . $body[0];
-		$body[-1] .= '}';
-		return @body;
+		my @list = map { my @x = ( qq("$_":), _JSONify( $$value{$_} ) ); $x[-1] .= ','; @x } @tags;
+		return '{}' unless @list;
+		$list[0]  =~ s/^/\{/;
+		$list[-1] =~ s/,?$/\}/;
+		return @list;
 	}
 
 	if ( ref($value) eq 'ARRAY' ) {
-		my @array = @$value;
-		my @tail  = map { _JSONify($_) } grep {defined} pop @array;
-		my @body  = map { my @x = _JSONify($_); $x[-1] .= ','; @x } @array;
-		return ( '[', @body, @tail, ']' );
+		my @list = map { my @x = _JSONify($_); $x[-1] .= ','; @x } @$value;
+		return '[]' unless @list;
+		$list[0]  =~ s/^/\[/;
+		$list[-1] =~ s/,?$/\]/;
+		return @list;
 	}
 
 	my $string = "$value";		## stringify, then use isdual() as discriminant
@@ -286,8 +286,8 @@
 	for ($string) {
 		unless ( utf8::is_utf8($value) ) {
 			return $_ if /^-?\d+$/;			# integer (string representation)
-			return $_ if /^-?\d+\.\d+$/;		# non-integer
-			return $_ if /^-?\d+(\.\d+)?e[+-]\d\d?$/i;
+			return $_ if /^-?\d+\.\d*$/;		# non-integer
+			return $_ if /^-?\d+(\.\d*)?[Ee][+-]?\d+$/;    # with exponent
 		}
 		s/\\/\\\\/g;					# escaped escape
 		s/^"(.*)"$/$1/;					# strip enclosing quotes
@@ -298,14 +298,24 @@
 
 
 ## no critic ProhibitMultiplePackages
-package Net::DNS::RR::OPT::NSID;				# RFC5001
+package Net::DNS::RR::OPT::UPDATE_LEASE;			# RFC9664
+my @field2 = qw(LEASE KEY-LEASE);
 
 sub _compose {
-	my ( undef, @argument ) = map { ref($_) ? %$_ : $_ } @_;
-	return pack 'H*', pop @argument;
+	my ( undef, @argument ) = @_;
+	for ( ref( $argument[0] ) ) {
+		@argument = @{$argument[0]}	     if /ARRAY/;
+		@argument = @{$argument[0]}{@field2} if /HASH/;
+	}
+	return pack 'NN*', grep {defined} @argument;
 }
 
-sub _decompose { return pack 'U0a*', unpack 'H*', pop @_ }	# mark as UTF-8
+sub _decompose {
+	my @time = grep {defined} unpack 'N*', pop @_;
+	my ( %object, $i );
+	$object{$field2[$i++]} = $_ foreach @time;
+	return \%object;
+}
 
 
 package Net::DNS::RR::OPT::DAU;					# RFC6975
@@ -326,7 +336,6 @@
 
 
 package Net::DNS::RR::OPT::CLIENT_SUBNET;			# RFC7871
-
 my %family = qw(1 Net::DNS::RR::A	2 Net::DNS::RR::AAAA);
 my @field8 = qw(FAMILY SOURCE-PREFIX SCOPE-PREFIX ADDRESS);
 
@@ -359,13 +368,11 @@
 }
 
 sub _decompose {
-	my $argument = pop @_;
-	return {'EXPIRE-TIMER' => unpack 'N', $argument};
+	return {'EXPIRE-TIMER' => unpack 'N', pop @_};
 }
 
 
 package Net::DNS::RR::OPT::COOKIE;				# RFC7873
-
 my @field10 = qw(CLIENT SERVER);
 
 sub _compose {
@@ -392,8 +399,7 @@
 }
 
 sub _decompose {
-	my $argument = pop @_;
-	return {'TIMEOUT' => unpack 'n', $argument};
+	return {'TIMEOUT' => unpack 'n', pop @_};
 }
 
 
@@ -439,7 +445,7 @@
 
 sub _compose {
 	my ( undef, @arg ) = @_;
-	my %arg	 = ref( $arg[0] ) ? %{$arg[0]} : @arg;
+	my %arg	 = ( 'INFO-CODE' => 0, ref( $arg[0] ) ? %{$arg[0]} : @arg );
 	my $text = join '', Net::DNS::RR::OPT::_JSONify( $arg{'EXTRA-TEXT'} || '' );
 	return pack 'na*', $arg{'INFO-CODE'}, Net::DNS::Text->new($text)->raw;
 }
@@ -447,13 +453,13 @@
 sub _decompose {
 	my ( $code, $text ) = unpack 'na*', pop @_;
 	my $error = $Net::DNS::Parameters::dnserrorbyval{$code};
-	my @error = defined($error) ? ( 'ERROR' => $error ) : ();
+	my @error = defined($error) ? ( 'ERROR-TEXT' => $error ) : ();
 	my $extra = Net::DNS::Text->decode( \$text, 0, length $text );
 	for ( $extra->value ) {
-		last unless /^[\[\{]/;
-		s/[`]([^`]*)[`]/$1/g;	## suppress backticks
-		s/([\$\@])/\\$1/g;	## Here be dragons!
-		my $REGEX = q/("[^"]*"|[\[\]{}:,]|[-0-9.Ee+]+)|\s+|(.)/;
+		last unless /^\s*[\{]/;
+		s/([\$\@])/\\$1/g;	## suppress interpolation within quoted strings
+		## extract JSON lexical tokens, discard unmatched characters  
+		my $REGEX = q/("[^"]*")|([-+]?\d+\.?\d*(?:[Ee][-+]?\d+)?)|::|([{}:,\[\]])|./;
 		my @split = grep { defined && length } split /$REGEX/o;
 		my $value = eval join( ' ', 'no integer;', map { s/^:$/=>/; $_ } @split );
 		return {'INFO-CODE' => $code, @error, 'EXTRA-TEXT' => $value} if ref($value);
@@ -476,7 +482,6 @@
 
 
 package Net::DNS::RR::OPT::ZONEVERSION;				# RFC9660
-
 my @field19 = qw(LABELCOUNT TYPE VERSION);
 
 sub _compose {
@@ -489,12 +494,28 @@
 }
 
 sub _decompose {
-	my %object;
 	my ( $l, $t, $v ) = unpack 'C2H*', pop @_;
+	my %object;
 	@object{@field19} = ( $l, $t, pack 'U0a*', $v );	# mark hex data as UTF-8
 	return \%object;
 }
 
+
+package Net::DNS::RR::OPT::MQTYPE_RESPONSE;			# RFC10029
+
+sub _compose {
+	my ( undef, @mqtype ) = map { ref($_) ? @$_ : $_ } @_;
+	return pack 'n*', map { Net::DNS::Parameters::typebyname($_) } @mqtype;
+}
+
+sub _decompose {
+	my @mqtype = unpack 'n*', pop @_;
+	return [map { Net::DNS::Parameters::typebyval($_) } @mqtype];
+}
+
+package Net::DNS::RR::OPT::MQTYPE_QUERY;			# RFC10029
+our @ISA = qw(Net::DNS::RR::OPT::MQTYPE_RESPONSE);
+
 ########################################
 
 
diff -Nru libnet-dns-perl-1.56/lib/Net/DNS/RR/RRSIG.pm libnet-dns-perl-1.57/lib/Net/DNS/RR/RRSIG.pm
--- libnet-dns-perl-1.56/lib/Net/DNS/RR/RRSIG.pm	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/lib/Net/DNS/RR/RRSIG.pm	2026-09-01 13:38:07.000000000 +0200
@@ -2,7 +2,7 @@
 
 use strict;
 use warnings;
-our $VERSION = (qw$Id: RRSIG.pm 2057 2026-07-16 10:05:04Z willem $)[2];
+our $VERSION = (qw$Id: RRSIG.pm 2059 2026-08-28 10:04:18Z willem $)[2];
 
 use base qw(Net::DNS::RR);
 
@@ -32,7 +32,8 @@
 my @algorithms;
 my @deprecated;
 if (DNSSEC) {
-	foreach my $class ( map {"Net::DNS::SEC::$_"} qw(Private DSA RSA ECDSA EdDSA Digest SM2) ) {
+	my @module = qw(Private DSA RSA ECDSA EdDSA MLDSA Digest);
+	foreach my $class ( map {"Net::DNS::SEC::$_"} @module ) {
 		my @index = eval join '', qw(r e q u i r e), " $class; ${class}::_index()";	## no critic
 		push @algorithms, map { ( $_ => $class ) } @index;
 		push @deprecated, eval "${class}::_deprecate()";			   	## no critic
@@ -352,6 +353,7 @@
 		'ED25519'	     => 15,			# [RFC8080]
 		'ED448'		     => 16,			# [RFC8080]
 		'SM2SM3'	     => 17,			# [RFC9563]
+		'MLDSA44'	     => 18,			# [draft-westerbaan-dnssec-mldsa]
 		'ECC-GOST12'	     => 23,			# [RFC9558]
 
 		'INDIRECT'   => 252,				# [RFC4034]
@@ -572,8 +574,8 @@
 	use Net::DNS::SEC;
 	$sigrr = Net::DNS::RR::RRSIG->create(
 				\@rrset, $keypath,
-				sigex => 20251230010101,
-				sigin => 20251201010101
+				sigex => 20261230010101,
+				sigin => 20261201010101
 				);
 
 	$sigrr->verify( \@rrset, $keyrr ) || die $sigrr->vrfyerrstr;
@@ -698,8 +700,8 @@
 
 	$sigrr = Net::DNS::RR::RRSIG->create(
 				\@rrsetref, $keypath,
-				sigex => 20251230010101,
-				sigin => 20251201010101
+				sigex => 20261230010101,
+				sigin => 20261201010101
 				);
 	$sigrr->print;
 
@@ -725,8 +727,8 @@
 The optional remaining arguments consist of ( name => value ) pairs
 as follows:
 
-	sigex	=> 20251230010101,	# signature expiration
-	sigin	=> 20251201010101,	# signature inception
+	sigex	=> 20261230010101,	# signature expiration
+	sigin	=> 20261201010101,	# signature inception
 	sigval	=> 30,			# validity window (days)
 	ttl	=> 3600
 
diff -Nru libnet-dns-perl-1.56/lib/Net/DNS/RR/TSIG.pm libnet-dns-perl-1.57/lib/Net/DNS/RR/TSIG.pm
--- libnet-dns-perl-1.56/lib/Net/DNS/RR/TSIG.pm	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/lib/Net/DNS/RR/TSIG.pm	2026-09-01 13:38:07.000000000 +0200
@@ -2,7 +2,7 @@
 
 use strict;
 use warnings;
-our $VERSION = (qw$Id: TSIG.pm 2003 2025-01-21 12:06:06Z willem $)[2];
+our $VERSION = (qw$Id: TSIG.pm 2060 2026-08-31 11:29:36Z willem $)[2];
 
 use base qw(Net::DNS::RR);
 
@@ -34,7 +34,9 @@
 sub _decode_rdata {			## decode rdata from wire-format octet string
 	my ( $self, $data, $offset ) = @_;
 
-	my $limit = $offset + $self->{rdlength};
+	my $limit = $offset + delete $self->{rdlength};
+	croak('misplaced or corrupt TSIG') unless $limit == length $$data;
+
 	( $self->{algorithm}, $offset ) = Net::DNS::DomainName->decode( $data, $offset );
 
 	# Design decision: Use 32 bits, which will work until the end of time()!
@@ -52,7 +54,6 @@
 	$self->{other} = unpack "\@$offset xx a$other_size", $$data;
 	$offset += $other_size + 2;
 
-	croak('misplaced or corrupt TSIG') unless $limit == length $$data;
 	my $raw = substr $$data, 0, $self->{offset}++;
 	$self->{rawref} = \$raw;
 	return;
@@ -62,16 +63,17 @@
 sub _encode_rdata {			## encode rdata as wire-format octet string
 	my $self = shift;
 
-	my $offset  = shift;
-	my $undef   = shift;
-	my $message = shift;
-	my $macbin  = $self->macbin;
+	my $offset    = shift;
+	my $undef     = shift;
+	my $message   = shift;
+	my $algorithm = $self->{algorithm} || return '';
+	my $macbin    = $self->macbin;
 	unless ($macbin) {
 		my $sigdata = $self->sig_data($message);	# form data to be signed
 		$macbin = $self->macbin( $self->_mac_function($sigdata) );
 	}
 
-	my $rdata = $self->{algorithm}->canonical;
+	my $rdata = $algorithm->canonical;
 
 	# Design decision: Use 32 bits, which will work until the end of time()!
 	$rdata .= pack 'xxN n', $self->time_signed, $self->fudge;
@@ -115,9 +117,10 @@
 
 
 sub string {				## override RR method
-	my $self	= shift;
-	my $owner	= $self->{owner}->string;
-	my $type	= $self->type;
+	my $self = shift;
+	my $name = $self->{owner}->string;
+	my $type = $self->type;
+	return "; $name	$type	; no data" unless $self->{algorithm};
 	my $algorithm	= $self->algorithm;
 	my $time_signed = $self->time_signed;
 	my $fudge	= $self->fudge;
@@ -127,12 +130,12 @@
 	my $other	= $self->other;
 
 	return <<"QQ";
-; $owner	$type	
+; $name	$type	
 ;	algorithm:	$algorithm
 ;	time signed:	$time_signed	fudge:	$fudge
 ;	signature:	$signature
 ;	original id:	$original_id
-;			$error	$other
+;	error:		$error	$other
 QQ
 }
 
@@ -251,8 +254,7 @@
 		local $message->{additional} = \@unsigned;	# remake header image
 		my @part = qw(question answer authority additional);
 		my @size = map { scalar @{$message->{$_}} } @part;
-		if ( my $rawref = $self->{rawref} ) {
-			delete $self->{rawref};
+		if ( my $rawref = delete $self->{rawref} ) {
 			my $hbin = pack 'n6', $self->original_id, $message->{status}, @size;
 			$message = join '', $hbin, substr $$rawref, length $hbin;
 		} else {
@@ -746,7 +748,7 @@
 The generated key must be added to the /etc/named.conf configuration
 or a separate file introduced by the $INCLUDE directive:
 
-	key "host1-host2.example. {
+	key "host1-host2.example." {
 		algorithm hmac-sha256;
 		secret "Secret+known+only+by+participating+entities=";
 	};
diff -Nru libnet-dns-perl-1.56/lib/Net/DNS/Resolver/UNIX.pm libnet-dns-perl-1.57/lib/Net/DNS/Resolver/UNIX.pm
--- libnet-dns-perl-1.56/lib/Net/DNS/Resolver/UNIX.pm	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/lib/Net/DNS/Resolver/UNIX.pm	2026-09-01 13:38:07.000000000 +0200
@@ -2,7 +2,7 @@
 
 use strict;
 use warnings;
-our $VERSION = (qw$Id: UNIX.pm 2053 2026-07-07 10:18:23Z willem $)[2];
+our $VERSION = (qw$Id: UNIX.pm 2059 2026-08-28 10:04:18Z willem $)[2];
 
 
 =head1 NAME
@@ -44,9 +44,10 @@
 		close $pipe;
 		return @retval;
 	} else {
+		local %ENV = ( PATH => '/bin:/usr/bin' );
 		local $SIG{__WARN__} = sub { };
 		warn 'child process fails without warning';
-		eval { exec $prog, @arg };
+		eval { exec {$prog} $prog, @arg };
 		exit;			## uncoverable statement
 	}
 }
diff -Nru libnet-dns-perl-1.56/lib/Net/DNS.pm libnet-dns-perl-1.57/lib/Net/DNS.pm
--- libnet-dns-perl-1.56/lib/Net/DNS.pm	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/lib/Net/DNS.pm	2026-09-01 13:38:07.000000000 +0200
@@ -4,9 +4,9 @@
 use warnings;
 
 our $VERSION;
-$VERSION = '1.56';
+$VERSION = '1.57';
 $VERSION = eval {$VERSION};
-our $SVNVERSION = (qw$Id: DNS.pm 2058 2026-07-17 10:09:31Z willem $)[2];
+our $SVNVERSION = (qw$Id: DNS.pm 2061 2026-09-01 11:37:52Z willem $)[2];
 
 
 =head1 NAME
diff -Nru libnet-dns-perl-1.56/t/05-OPT.t libnet-dns-perl-1.57/t/05-OPT.t
--- libnet-dns-perl-1.56/t/05-OPT.t	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/t/05-OPT.t	2026-09-01 13:38:07.000000000 +0200
@@ -1,10 +1,10 @@
 #!/usr/bin/perl
-# $Id: 05-OPT.t 1996 2024-12-16 13:05:08Z willem $	-*-perl-*-
+# $Id: 05-OPT.t 2059 2026-08-28 10:04:18Z willem $	-*-perl-*-
 #
 
 use strict;
 use warnings;
-use Test::More tests => 89;
+use Test::More tests => 94;
 use TestToolkit;
 
 use Net::DNS;
@@ -77,16 +77,9 @@
 }
 
 
-my $edns = Net::DNS::Packet->new()->edns;
-
-foreach my $option ( keys %Net::DNS::Parameters::ednsoptionbyval ) {
-	$edns->option( $option => {'BASE16' => '076578616d706c6500'} );
-}
-
-
 my @testcase = (
-	["LLQ" => {"BASE16" => "000100000000000000000000000000000000"}],
-	[["NSID" => {"OPTION-DATA" => "rawbytes"}], ["NSID" => {"IDENTIFIER" => "7261776279746573"}]],
+	["UPDATE-LEASE"	 => [86400, 604800]],
+	["NSID"		 => {"OPTION-DATA" => "rawbytes"}],
 	["4"		 => {"OPTION-DATA" => ""}],
 	["DAU"		 => ( 8, 10, 13, 14, 15, 16 )],
 	["DHU"		 => ( 1, 2,  4 )],
@@ -97,18 +90,23 @@
 	[["COOKIE" => ["7261776279746573", ""]], ["COOKIE" => "7261776279746573"]],
 	["TCP-KEEPALIVE" => 200],
 	[["PADDING" => {"OPTION-DATA" => ""}], ["PADDING" => 0], ["PADDING" => ""]],
-	["PADDING"	  => {"OPTION-DATA" => "rawbytes"}],
-	["PADDING"	  => 100],
-	["CHAIN"	  => {"BASE16" => "076578616d706c6500"}],
-	["KEY-TAG"	  => ( 29281, 30562, 31092, 25971 )],
-	["EXTENDED-ERROR" => ( "INFO-CODE"    => 0, "EXTRA-TEXT" => '{"JSON":"EXAMPLE"}' )],
-	["EXTENDED-ERROR" => ( "INFO-CODE"    => 0, "EXTRA-TEXT" => '{JSON: unparsable}' )],
-	["EXTENDED-ERROR" => ( "INFO-CODE"    => 123 )],
-	["REPORT-CHANNEL" => ( "AGENT-DOMAIN" => "example." )],
+	["PADDING"	    => {"OPTION-DATA" => "rawbytes"}],
+	["PADDING"	    => 100],
+	["CHAIN"	    => {"BASE16" => "076578616d706c6500"}],
+	["KEY-TAG"	    => ( 29281, 30562, 31092, 25971 )],
+	["EXTENDED-ERROR"   => ( "INFO-CODE" => 123 )],
+	["EXTENDED-ERROR"   => ( "INFO-CODE" => 0, "EXTRA-TEXT" => '{JSON: unparsable}' )],
+	["EXTENDED-ERROR"   => ( "INFO-CODE" => 0, "EXTRA-TEXT" => '{"JSON":"EXAMPLE"}' )],
+	["STRUCTURED-ERROR" => {"OPTION-LENGTH" => 0}],
+	["REPORT-CHANNEL"   => ( "AGENT-DOMAIN" => "example." )],
 	[["ZONEVERSION" => ""], ["ZONEVERSION" => {"OPTION-DATA" => ""}], ["ZONEVERSION" => []]],
-	["ZONEVERSION" => [2, 0, "12345678"]],
+	["ZONEVERSION"	=> [2, 0, "12345678"]],
+	["MQTYPE-QUERY" => ( 43, 48 )],
 	);
 
+
+my $edns = Net::DNS::Packet->new()->edns;
+
 foreach (@testcase) {
 	my ( $canonical, @alternative ) = ref( $$_[0] ) eq 'ARRAY' ? @$_ : $_;
 	my ( $option,	 @value )	= @$canonical;
@@ -137,6 +135,8 @@
 is( Net::DNS::RR::OPT::_JSONify('1e+20'), '1e+20',     '_JSONify string with exponent' );
 is( Net::DNS::RR::OPT::_JSONify('abcde'), '"abcde"',   '_JSONify non-numeric string' );
 is( Net::DNS::RR::OPT::_JSONify('\\092'), '"\\\\092"', '_JSONify escape character' );
+is( Net::DNS::RR::OPT::_JSONify( [] ),	  '[]',	       '_JSONify empty array' );
+is( Net::DNS::RR::OPT::_JSONify( {} ),	  '{}',	       '_JSONify empty hash' );
 
 my @json = Net::DNS::RR::OPT::_JSONify( {'BASE16' => '1234'} );
 is( "@json", qq[{"BASE16": "1234"}], 'short BASE16 string' );
diff -Nru libnet-dns-perl-1.56/t/05-TSIG.t libnet-dns-perl-1.57/t/05-TSIG.t
--- libnet-dns-perl-1.56/t/05-TSIG.t	2026-07-17 12:09:44.000000000 +0200
+++ libnet-dns-perl-1.57/t/05-TSIG.t	2026-09-01 13:38:07.000000000 +0200
@@ -1,5 +1,5 @@
 #!/usr/bin/perl
-# $Id: 05-TSIG.t 1980 2024-06-02 10:16:33Z willem $	-*-perl-*-
+# $Id: 05-TSIG.t 2060 2026-08-31 11:29:36Z willem $	-*-perl-*-
 #
 
 use strict;
@@ -22,7 +22,7 @@
 	exit;
 }
 
-plan tests => 63;
+plan tests => 64;
 
 
 sub mysign {
@@ -44,6 +44,7 @@
 
 my $typecode = unpack 'xn', Net::DNS::RR->new( type => $type )->encode;
 is( $typecode, $code, "$type RR type code = $code" );
+ok( Net::DNS::RR->new( type => $type )->string, 'minimal rr->string' );
 
 my $hash = {keybin => pack( 'H*', '66616b65206b6579' )};
 @{$hash}{@attr} = @data;
@@ -51,7 +52,7 @@
 
 for my $rr ( Net::DNS::RR->new( name => $name, type => $type, %$hash ) ) {
 	my $string = $rr->string;
-	like( $rr->string, "/$$hash{algorithm}/", 'got expected rr->string' );
+	like( $rr->string, "/$$hash{algorithm}/", 'populated rr->string' );
 
 	foreach (@attr) {
 		is( $rr->$_, $hash->{$_}, "expected result from rr->$_()" );


More information about the pkg-perl-maintainers mailing list