Hi!
On Sun, 2026-03-22 at 16:13:28 +0000, Oron Peled wrote:
> Package: libdpkg-perl
> Version: 1.22.22
> Severity: normal
> * What led up to the situation?
> - In "trixie" trying to use "Dpkg::Version::version_compare" fails
I assume this is meant in the context of "sort version_compare @versions".
> - The error was very clear:
> "Use of uninitialized value $a in string at
> /usr/share/perl5/Dpkg/Version.pm
> line 271, <> line 266."
Ack.
> * The root cause is in commit (appeared before version 1.22.12):
> "a9b22de4db4d42417c4cac74e7e537f48284e731 perl: Remove function prototypes"
>
> * Removing prototype of a sort function affects its semantics.
> From "sort" documentation in perlfunc man page:
> "If the subroutine's prototype is "($$)", the elements to be compared
> are passed by reference in @_, as for a normal subroutine."
>
> * But the existing code still expect parameters in @_
> (which is empty after prototype removal)
>
> * Minimal fix: re-add the missing prototype to that function
I've done this (using the signatures syntax so that the code can then
still be switched to use full sub signatures), with the attached change,
and included a matching change for Dpkg::Deps, where I noticed that it
always had that same problem (so not a regression). I'll add some unit
tests and queue these for the next dpkg upload (1.23.x), and I'll mark
the Dpkg::Version change for a stable update (1.22.x) fix.
> * Alternative fix: use $a and $b directly and don't assign them from @_
This would mean you cannot call this with parameters, which would
break way more code I think (at least from within dpkg itself), and
turns into a way more surprising API.
> * My temporary workaround: wrote a small wrapper that pass $a and $b as
> explicit
> parameters
Thanks for the report and investigation!
Regards,
Guillem
diff --git i/scripts/Dpkg/Deps.pm w/scripts/Dpkg/Deps.pm
index 6ac2f5247..c3684643d 100644
--- i/scripts/Dpkg/Deps.pm
+++ w/scripts/Dpkg/Deps.pm
@@ -409,7 +409,8 @@ my %relation_ordering = (
REL_LE() => 5,
);
-sub deps_compare {
+sub deps_compare :prototype($$)
+{
my ($aref, $bref) = @_;
my (@as, @bs);
diff --git i/scripts/Dpkg/Version.pm w/scripts/Dpkg/Version.pm
index 894268a8a..e304128ec 100644
--- i/scripts/Dpkg/Version.pm
+++ w/scripts/Dpkg/Version.pm
@@ -301,7 +301,8 @@ If $a or $b are not valid version numbers, it dies with an error.
=cut
-sub version_compare {
+sub version_compare :prototype($$)
+{
my ($a, $b) = @_;
my $va = Dpkg::Version->new($a, check => 1);
defined($va) || error(g_('%s is not a valid version'), "$a");
@@ -398,7 +399,8 @@ sub _version_order {
}
}
-sub version_compare_string {
+sub version_compare_string :prototype($$)
+{
my @a = map { _version_order($_) } split(//, shift);
my @b = map { _version_order($_) } split(//, shift);
while (1) {
@@ -423,7 +425,8 @@ $a is earlier than $b, 0 if they are equal and 1 if $a is later than $b.
=cut
-sub version_compare_part {
+sub version_compare_part :prototype($$)
+{
my @a = version_split_digits(shift);
my @b = version_split_digits(shift);
while (1) {