Package: libregexp-pattern-license-perl Version: v3.10.0 This package (as distributed on CPAN) will fail tests on Perl 5.37.10. The code exploits historically undefined behavior which has become defined in 5.37.10.
Historically perl would "accumulate" capture buffer data in a quantified subgroup in a regular expression, eg, "abc"=~/(?:(a)|(b)|(c))+/ would leave $1, $2, $3 defined as "a", "b", "c". This behavior is problematic and has been changed in Perl 5.37.10 so that after such an expression only one of the three capture buffers will be defined, that which was matched in the last iteration of the quantified group. The test code for Regexp::Pattern::License exploits this undefined behavior to accumulate the results of multiple iterations of a quantified group. Replacing that code with a while (/.../g) loop fixes the problem. The attached patch fixes it so that the code should work on older and newer perls regardless as to the status of this undefined behavior. Note this perl package uses the debian bug tracker, however this bug is visible on any platform using Perl 5.37.10 or later. I am not filing this bug report from a debian install, so I cannot provide any of the debian specific data you request on your bug tracker page. Also please note that https://metacpan.org/pod/Regexp::Pattern::License specifies that the source code repository for this package is https://salsa.debian.org/build-common-team/regexp-pattern-license.git however that code does not build as it has incomplete Dist::Zilla configuration. Thus I was not able to produce a patch against your repo, the attached patch is against the released code on CPAN. See also the "BBC" (Blead Breaks CPAN) Perl5 bug report ticket for this: https://github.com/Perl/perl5/issues/21001 cheers, Yves -- perl -Mre=debug -e "/just|another|perl|hacker/"
commit 326895d48bbf9fb23d5dd121724c9456238ce7df Author: Yves Orton <demer...@gmail.com> Date: Sat Apr 1 15:41:19 2023 +0200 LicenseRegistry.pm - do not rely on undefined regex behavior Using multiple capture buffers inside of a quantified group has undefined behavior, and in modern perls only one of the capture groups will be defined, whereas in older perls the different matches will accumulate and overwrite each other. Using while /g matches allows us to get the same behavior as before without relying on the undefined behavior. diff --git a/t/lib/Test2/Tools/LicenseRegistry.pm b/t/lib/Test2/Tools/LicenseRegistry.pm index 199acc3..0dfec0a 100644 --- a/t/lib/Test2/Tools/LicenseRegistry.pm +++ b/t/lib/Test2/Tools/LicenseRegistry.pm @@ -14,15 +14,17 @@ my %RE = %Regexp::Pattern::License::RE; my $any = '[A-Za-z_][A-Za-z0-9_]*'; my $str = '[A-Za-z][A-Za-z0-9_]*'; -my $re_prop_attrs = qr/ - \A(?'prop'$str)\.alt(?: +my $_re_prop_start = qr/ + \A(?'prop'$str)\.alt +/x; +my $_re_prop_attrs = qr/\G(?: \.org\.(?'org'$str)| \.version\.(?'version'$str)| \.since\.date_(?'since_date'\d{8})| \.until\.date_(?'until_date'\d{8})| \.synth\.$any| (?'other'\.$any) - )*\z/x; + )/x; sub license_org_metadata { @@ -68,28 +70,35 @@ sub get_org_props my ( @main, @extra, $skipcount ); for ( keys %{ $RE{$key} } ) { - /$re_prop_attrs/; - next unless $+{prop} and $+{prop} eq $prop; - next unless $+{org} and $+{org} eq $org; - next if $+{version}; - if ( $+{since_date} ) { - if ( defined $date and 1 < $date and $date < $+{since_date} ) { - $skipcount++ unless $+{other}; + my %props; + if (m/$_re_prop_start/g){ + %props = %+; + while (m/$_re_prop_attrs/g) { + $props{$_} = $+{$_} for keys %+; + } + } + + next unless $props{prop} and $props{prop} eq $prop; + next unless $props{org} and $props{org} eq $org; + next if $props{version}; + if ( $props{since_date} ) { + if ( defined $date and 1 < $date and $date < $props{since_date} ) { + $skipcount++ unless $props{other}; next; } } - if ( $+{until_date} ) { - if ( not defined $date or $+{until_date} <= $date ) { - $skipcount++ unless $+{other}; + if ( $props{until_date} ) { + if ( not defined $date or $props{until_date} <= $date ) { + $skipcount++ unless $props{other}; next; } } elsif ( defined $date and $date == 0 ) { - $skipcount++ unless $+{other}; + $skipcount++ unless $props{other}; next; } - if ( $+{other} ) { + if ( $props{other} ) { push @extra, $RE{$key}{$_}; } else {