Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ack for openSUSE:Factory checked in 
at 2026-06-08 14:23:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ack (Old)
 and      /work/SRC/openSUSE:Factory/.ack.new.2375 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ack"

Mon Jun  8 14:23:21 2026 rev:40 rq:1357898 version:3.10.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/ack/ack.changes  2025-05-30 17:19:49.353501517 
+0200
+++ /work/SRC/openSUSE:Factory/.ack.new.2375/ack.changes        2026-06-08 
14:28:21.204607209 +0200
@@ -1,0 +2,10 @@
+Mon Jun  8 08:07:01 UTC 2026 - Jan Baier <[email protected]>
+
+- ack 3.10.0:
+  * CVE-2026-49147: filename ANSI escape sequences
+  * CVE-2026-49146: project .ackrc -A -B -C memory exhaustion
+  * CVE-2026-49145: project .ackrc --follow / --files-from file exfiltration
+  * Fixed a bug where types set in the .ackrc could not be overridden from the
+    command line. Thanks, Dmitri Vereshchagin. (GH #393)
+
+-------------------------------------------------------------------

Old:
----
  ack-v3.9.0.tar.gz

New:
----
  ack-v3.10.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ack.spec ++++++
--- /var/tmp/diff_new_pack.X5DBzq/_old  2026-06-08 14:28:21.940637750 +0200
+++ /var/tmp/diff_new_pack.X5DBzq/_new  2026-06-08 14:28:21.948638081 +0200
@@ -1,8 +1,8 @@
 #
 # spec file for package ack
 #
-# Copyright (c) 2023 SUSE LLC
 # Copyright (c) 2025 Andreas Stieger <[email protected]>
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 
 Name:           ack
-Version:        3.9.0
+Version:        3.10.0
 Release:        0
 Summary:        Grep-Like Text Finder
 License:        Artistic-2.0
@@ -31,9 +31,9 @@
 BuildRequires:  perl >= 5.10.1
 BuildRequires:  perl(File::Next) >= 1.18
 BuildRequires:  perl(File::Temp) >= 0.19
-BuildRequires:  perl(YAML::PP)
 BuildRequires:  perl(IO::Pty)
 BuildRequires:  perl(Test::Pod) >= 1.14
+BuildRequires:  perl(YAML::PP)
 Requires:       perl >= 5.10.1
 Requires:       perl-App-Ack = %{version}-%{release}
 Requires:       perl-base = %{perl_version}

++++++ ack-v3.9.0.tar.gz -> ack-v3.10.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/Changes new/ack-v3.10.0/Changes
--- old/ack-v3.9.0/Changes      2025-05-26 22:27:07.000000000 +0200
+++ new/ack-v3.10.0/Changes     2026-06-07 18:50:50.000000000 +0200
@@ -1,6 +1,17 @@
 History file for ack 3.  https://beyondgrep.com/
 
-NEXT
+v3.10.0     Sun Jun  7 11:50:37 CDT 2026
+========================================
+[SECURITY]
+CVE-2026-49147: filename ANSI escape sequences
+CVE-2026-49146: project .ackrc -A -B -C memory exhaustion
+CVE-2026-49145: project .ackrc --follow / --files-from file exfiltration
+
+[FIXES]
+Fixed a bug where types set in the .ackrc could not be overridden from the
+command line. Thanks, Dmitri Vereshchagin. (GH #393)
+
+
 v3.9.0      Mon May 26 15:02:57 CDT 2025
 ========================================
 The --not option can be used with either --and or --or.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/MANIFEST new/ack-v3.10.0/MANIFEST
--- old/ack-v3.9.0/MANIFEST     2025-05-26 22:27:24.000000000 +0200
+++ new/ack-v3.10.0/MANIFEST    2026-06-07 18:51:54.000000000 +0200
@@ -65,9 +65,11 @@
 t/ack-print0.t
 t/ack-proximate.yaml
 t/ack-s.t
+t/ack-s.yaml
 t/ack-show-types.t
 t/ack-type-del.t
 t/ack-type.t
+t/ack-type.yaml
 t/ack-v.yaml
 t/ack-version.t
 t/ack-w.t
@@ -105,6 +107,7 @@
 t/incomplete-last-line.t
 t/interactive.t
 t/invalid-ackrc.t
+t/invalid-context.t
 t/invalid-options.t
 t/is-filter.t
 t/line-endings.t
@@ -115,8 +118,10 @@
 t/mutex-options.t
 t/mutex.yaml
 t/named-pipes.t
+t/naughty-filenames.t
 t/needs-line-scan.t
 t/noackrc.t
+t/no-re-eval.t
 t/noenv.t
 t/prescan-line-boundaries.t
 t/process-substitution.t
@@ -151,6 +156,7 @@
 t/swamp/Rakefile
 t/swamp/Sample.ascx
 t/swamp/Sample.asmx
+t/swamp/bad-ascii.tar.GZ
 t/swamp/blib/ignore.pm
 t/swamp/blib/ignore.pod
 t/swamp/c-header.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/META.json new/ack-v3.10.0/META.json
--- old/ack-v3.9.0/META.json    2025-05-26 22:27:24.000000000 +0200
+++ new/ack-v3.10.0/META.json   2026-06-07 18:51:54.000000000 +0200
@@ -75,5 +75,5 @@
       },
       "x_MailingList" : "https://groups.google.com/group/ack-users";
    },
-   "version" : "v3.9.0"
+   "version" : "v3.10.0"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/META.yml new/ack-v3.10.0/META.yml
--- old/ack-v3.9.0/META.yml     2025-05-26 22:27:24.000000000 +0200
+++ new/ack-v3.10.0/META.yml    2026-06-07 18:51:53.000000000 +0200
@@ -45,4 +45,4 @@
   homepage: https://beyondgrep.com/
   license: https://www.perlfoundation.org/artistic-license-20.html
   repository: git://github.com/beyondgrep/ack3.git
-version: v3.9.0
+version: v3.10.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/README.md new/ack-v3.10.0/README.md
--- old/ack-v3.9.0/README.md    2025-04-06 17:48:44.000000000 +0200
+++ new/ack-v3.10.0/README.md   2026-06-07 18:25:48.000000000 +0200
@@ -73,7 +73,7 @@
 
 # License
 
-Copyright 2005-2025 Andy Lester.
+Copyright 2005-2026 Andy Lester.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/ack new/ack-v3.10.0/ack
--- old/ack-v3.9.0/ack  2025-05-26 22:27:07.000000000 +0200
+++ new/ack-v3.10.0/ack 2026-06-07 18:50:56.000000000 +0200
@@ -3,10 +3,12 @@
 use strict;
 use warnings;
 
-our $VERSION = 'v3.9.0'; # Check https://beyondgrep.com/ for updates
+our $VERSION = 'v3.10.0'; # Check https://beyondgrep.com/ for updates
 
 use 5.010001;
 
+no re 'eval'; # Enforce default and block -Mre=eval to block RCE security 
problem.
+
 use File::Spec ();
 use File::Next ();
 use Getopt::Long ();
@@ -297,6 +299,13 @@
 
 exit 0;
 
+# Sanitize a filename for display: replace control chars with '?'
+sub _safe_filename {
+    my $s = shift;
+    $s =~ s/[^\x20-\x7E\t]/?/g;
+    return $s;
+}
+
 
 sub file_loop_fg {
     my $files = shift;
@@ -307,10 +316,10 @@
             App::Ack::show_types( $file );
         }
         elsif ( $opt_g ) {
-            print_line_with_options( undef, $file->name, 0, $App::Ack::ors );
+            print_line_with_options( undef, _safe_filename( $file->name ), 0, 
$App::Ack::ors );
         }
         else {
-            App::Ack::say( $file->name );
+            App::Ack::say( _safe_filename( $file->name ) );
         }
         ++$nmatches;
         last if defined($opt_m) && ($nmatches >= $opt_m);
@@ -615,7 +624,7 @@
 sub print_matches_in_file {
     my $file = shift;
 
-    my $filename  = $file->name;
+    my $filename = _safe_filename($file->name);
 
     my $fh = $file->open;
     if ( !$fh ) {
@@ -2002,8 +2011,8 @@
 
     Aspect      Option              Env. variable       Default
     --------    -----------------   ------------------  ---------------
-    filename    --color-filename    ACK_COLOR_FILENAME  black on_yellow
-    match       --color-match       ACK_COLOR_MATCH     bold green
+    filename    --color-filename    ACK_COLOR_FILENAME  bold green
+    match       --color-match       ACK_COLOR_MATCH     black on_yellow
     line no.    --color-lineno      ACK_COLOR_LINENO    bold yellow
     column no.  --color-colno       ACK_COLOR_COLNO     bold yellow
 
@@ -2395,6 +2404,7 @@
 How appropriate to have I<ack>nowledgements!
 
 Thanks to everyone who has contributed to ack in any way, including
+Dmitri Vereshchagin,
 Geraint Edwards,
 Loren Howard,
 Yaroslav Halchenko,
@@ -2531,7 +2541,7 @@
 
 =head1 COPYRIGHT & LICENSE
 
-Copyright 2005-2025 Andy Lester.
+Copyright 2005-2026 Andy Lester.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the Artistic License v2.0.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/lib/App/Ack/ConfigLoader.pm 
new/ack-v3.10.0/lib/App/Ack/ConfigLoader.pm
--- old/ack-v3.9.0/lib/App/Ack/ConfigLoader.pm  2025-05-26 21:16:00.000000000 
+0200
+++ new/ack-v3.10.0/lib/App/Ack/ConfigLoader.pm 2026-06-07 18:32:24.000000000 
+0200
@@ -124,8 +124,9 @@
     for ( my $i = 0; $i < @{ $opt->{filters} }; $i++ ) {
         my $opt_filter = @{ $opt->{filters} }[$i];
 
-        # XXX Do a real list comparison? This just checks string equivalence.
-        if ( $opt_filter->is_inverted() && "$opt_filter->{filter}" eq 
"@filters" ) {
+        if ( $opt_filter->is_inverted()
+            && grep { $_ == $opt_filter->{filter} } @filters )
+        {
             splice @{ $opt->{filters} }, $i, 1;
             $i--;
         }
@@ -176,6 +177,9 @@
             if ( not $value ) {
                 @filters = map { $_->invert() } @filters;
             }
+            else {
+                _uninvert_filter( $opt, @filters );
+            }
 
             push @{ $opt->{'filters'} }, @filters;
         };
@@ -369,8 +373,17 @@
 sub _context_value {
     my $val = shift;
 
-    # Contexts default to 2.
-    return (!defined($val) || ($val < 0)) ? 2 : $val;
+      # Contexts default to 2.
+      return 2 if !defined($val) || $val < 0;
+
+      if ( $val > 10_000 ) {
+          App::Ack::die(
+              "Context value $val exceeds the maximum allowed "
+              . "value of 10000."
+          );
+      }
+
+      return $val;
 }
 
 
@@ -423,6 +436,7 @@
             $args_for_source = {
                 %{$args_for_source},
                 'pager:s' => $illegal,
+                'follow!' => $illegal,
             };
         }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/lib/App/Ack/Filter/Extension.pm 
new/ack-v3.10.0/lib/App/Ack/Filter/Extension.pm
--- old/ack-v3.9.0/lib/App/Ack/Filter/Extension.pm      2023-02-25 
21:34:04.000000000 +0100
+++ new/ack-v3.10.0/lib/App/Ack/Filter/Extension.pm     2026-06-07 
18:33:08.000000000 +0200
@@ -12,6 +12,8 @@
 
 use strict;
 use warnings;
+no re 'eval'; # Enforce default and block -Mre=eval to block RCE security 
problem.
+
 use parent 'App::Ack::Filter';
 
 use App::Ack::Filter ();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/lib/App/Ack/Filter/FirstLineMatch.pm 
new/ack-v3.10.0/lib/App/Ack/Filter/FirstLineMatch.pm
--- old/ack-v3.9.0/lib/App/Ack/Filter/FirstLineMatch.pm 2023-02-25 
21:34:04.000000000 +0100
+++ new/ack-v3.10.0/lib/App/Ack/Filter/FirstLineMatch.pm        2026-06-07 
18:33:22.000000000 +0200
@@ -13,6 +13,8 @@
 
 use strict;
 use warnings;
+no re 'eval'; # Enforce default and block -Mre=eval to block RCE security 
problem.
+
 use parent 'App::Ack::Filter';
 
 sub new {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/lib/App/Ack/Filter/Match.pm 
new/ack-v3.10.0/lib/App/Ack/Filter/Match.pm
--- old/ack-v3.9.0/lib/App/Ack/Filter/Match.pm  2023-02-25 21:34:04.000000000 
+0100
+++ new/ack-v3.10.0/lib/App/Ack/Filter/Match.pm 2026-06-07 18:33:38.000000000 
+0200
@@ -2,6 +2,9 @@
 
 use strict;
 use warnings;
+
+no re 'eval'; # Enforce default and block -Mre=eval to block RCE security 
problem.
+
 use parent 'App::Ack::Filter';
 
 use App::Ack::Filter::MatchGroup ();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/lib/App/Ack/Filter/MatchGroup.pm 
new/ack-v3.10.0/lib/App/Ack/Filter/MatchGroup.pm
--- old/ack-v3.9.0/lib/App/Ack/Filter/MatchGroup.pm     2023-02-25 
21:34:04.000000000 +0100
+++ new/ack-v3.10.0/lib/App/Ack/Filter/MatchGroup.pm    2026-06-07 
18:33:50.000000000 +0200
@@ -13,6 +13,8 @@
 
 use strict;
 use warnings;
+no re 'eval'; # Enforce default and block -Mre=eval to block RCE security 
problem.
+
 use parent 'App::Ack::Filter';
 
 sub new {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/lib/App/Ack.pm 
new/ack-v3.10.0/lib/App/Ack.pm
--- old/ack-v3.9.0/lib/App/Ack.pm       2025-05-26 22:27:07.000000000 +0200
+++ new/ack-v3.10.0/lib/App/Ack.pm      2026-06-07 18:51:01.000000000 +0200
@@ -13,11 +13,13 @@
 
 =cut
 
+no re 'eval'; # enforce default, block -Mre=eval to block RCE security fail
+
 our $VERSION;
 our $COPYRIGHT;
 BEGIN {
-    $VERSION = 'v3.9.0'; # Check https://beyondgrep.com/ for updates
-    $COPYRIGHT = 'Copyright 2005-2025 Andy Lester.';
+    $VERSION = 'v3.10.0'; # Check https://beyondgrep.com/ for updates
+    $COPYRIGHT = 'Copyright 2005-2026 Andy Lester.';
 }
 our $STANDALONE = 0;
 our $ORIGINAL_PROGRAM_NAME;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/Util.pm new/ack-v3.10.0/t/Util.pm
--- old/ack-v3.9.0/t/Util.pm    2025-05-26 22:09:52.000000000 +0200
+++ new/ack-v3.10.0/t/Util.pm   2026-06-07 18:27:51.000000000 +0200
@@ -88,7 +88,7 @@
 
 sub prep_environment {
     my @ack_args   = qw( ACKRC ACK_PAGER HOME ACK_COLOR_MATCH 
ACK_COLOR_FILENAME ACK_COLOR_LINENO ACK_COLOR_COLNO );
-    my @taint_args = qw( PATH CDPATH IFS ENV );
+    my @taint_args = qw( PATH CDPATH IFS ENV PERLDOC );
     delete @ENV{ @ack_args, @taint_args };
 
     if ( is_windows() ) {
@@ -1232,6 +1232,18 @@
 
     my $perl = caret_X();
 
+    # ACK_TEST_MODULE_OPTS
+    # If a .t test file wishes to load a module for debug or provocation 
before Ack starts
+    # e.g.
+    # $ENV{'ACK_TEST_MODULE_OPTS'} = 're=eval' ; attempts to enable runtime 
code injection in REs
+    #    (which we block, but this is needed to test that we block it)
+    # $ENV{'ACK_TEST_MODULE_OPTS'} = 're=debug' ; would trace REs compilation 
and execution,
+    #    (which gets rather long so don't check in that way!)
+    if ($ENV{'ACK_TEST_MODULE_OPTS'}){
+        # warn "ACK_TEST_MODULE_OPTS=-M$ENV{'ACK_TEST_MODULE_OPTS'}" ;  
#############DEBUG #####
+        unshift( @cmd, "-M$ENV{'ACK_TEST_MODULE_OPTS'}" );
+    }
+
     if ( $ENV{'ACK_TEST_STANDALONE'} ) {
         unshift( @cmd, $perl );
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/ack-g.t new/ack-v3.10.0/t/ack-g.t
--- old/ack-v3.9.0/t/ack-g.t    2025-04-06 17:48:44.000000000 +0200
+++ new/ack-v3.10.0/t/ack-g.t   2025-05-26 23:36:25.000000000 +0200
@@ -3,62 +3,13 @@
 use warnings;
 use strict;
 
-use Test::More tests => 5;
+use Test::More tests => 2;
 
 use lib 't';
 use Util;
 
 prep_environment();
 
-subtest 'No starting directory specified' => sub {
-    plan tests => 3;
-
-    my $regex = 'non';
-
-    my @files = qw( t/foo/non-existent );
-    my @args = ( '-g', $regex );
-    my ($stdout, $stderr) = run_ack_with_stderr( @args, @files );
-
-    is_empty_array( $stdout, 'No STDOUT for non-existent file' );
-    is( scalar @{$stderr}, 1, 'One line of STDERR for non-existent file' );
-    like( $stderr->[0], qr/non-existent: No such file or directory/,
-        'Correct warning message for non-existent file' );
-};
-
-
-subtest 'regex comes before -g on the command line' => sub {
-    plan tests => 3;
-
-    my $regex = 'non';
-
-    my @files = qw( t/foo/non-existent );
-    my @args = ( $regex, '-g' );
-    my ($stdout, $stderr) = run_ack_with_stderr( @args, @files );
-
-    is_empty_array( $stdout, 'No STDOUT for non-existent file' );
-    is( scalar @{$stderr}, 1, 'One line of STDERR for non-existent file' );
-    like( $stderr->[0], qr/non-existent: No such file or directory/,
-        'Correct warning message for non-existent file' );
-};
-
-
-
-subtest 'test exit codes' => sub {
-    plan tests => 4;
-
-    my $file_regex = 'foo';
-    my @files      = ( 't/text/' );
-
-    run_ack( '-g', $file_regex, @files );
-    is( get_rc(), 1, '-g with no matches must exit with 1' );
-
-    $file_regex = 'raven';
-
-    run_ack( '-g', $file_regex, @files );
-    is( get_rc(), 0, '-g with matches must exit with 0' );
-};
-
-
 subtest 'test -g with --color' => sub {
     plan tests => 2;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/ack-g.yaml new/ack-v3.10.0/t/ack-g.yaml
--- old/ack-v3.9.0/t/ack-g.yaml 2025-05-26 21:16:00.000000000 +0200
+++ new/ack-v3.10.0/t/ack-g.yaml        2025-05-26 23:35:27.000000000 +0200
@@ -77,7 +77,7 @@
 name: -Q works on -g, part 2
 args: -g file.bar$ t -Q
 exitcode: 1
-stdout: |
+stdout:
 
 ---
 name: -w works on -g
@@ -148,3 +148,25 @@
   t/swamp/sample.aspx
   t/swamp/sample.rake
   t/swamp/test_foo.py
+
+---
+name: No starting directory specified
+args: -g non t/foo/non-existent
+exitcode: 1
+stdout:
+stderr: |
+  ack: t/foo/non-existent: No such file or directory
+
+---
+name: No files found returns 1
+args: -g foo t/text
+exitcode: 1
+stdout:
+stderr:
+
+---
+name: Files found returns 0
+args: -g raven t/text
+exitcode: 0
+stdout: |
+  t/text/raven.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/ack-s.t new/ack-v3.10.0/t/ack-s.t
--- old/ack-v3.9.0/t/ack-s.t    2024-12-21 05:11:28.000000000 +0100
+++ new/ack-v3.10.0/t/ack-s.t   2025-05-26 23:57:18.000000000 +0200
@@ -3,30 +3,13 @@
 use strict;
 use warnings;
 
-use Test::More tests => 4;
+use Test::More tests => 1;
 use lib 't';
 use Util;
 use File::Temp;
 
 prep_environment();
 
-WITHOUT_S: {
-    my @files = qw( non-existent-file.txt );
-    my @args  = qw( search-term );
-    my (undef, $stderr) = run_ack_with_stderr( @args, @files );
-
-    is( @{$stderr}, 1, 'Exactly one line of error' );
-    like( $stderr->[0], qr/\Qnon-existent-file.txt: No such file or 
directory\E/, q{Error if there's no file} );
-}
-
-WITH_S: {
-    my @files = qw( non-existent-file.txt );
-    my @args  = qw( search-term -s );
-    my (undef, $stderr) = run_ack_with_stderr( @args, @files );
-
-    is_empty_array( $stderr, 'Nothing in stderr' );
-}
-
 RESTRICTED_DIRECTORIES: {
     my @args = qw( hello -s );
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/ack-s.yaml new/ack-v3.10.0/t/ack-s.yaml
--- old/ack-v3.9.0/t/ack-s.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/ack-v3.10.0/t/ack-s.yaml        2025-05-26 23:41:46.000000000 +0200
@@ -0,0 +1,14 @@
+---
+name: Errors without -s
+args: search-term non-existent-file.txt
+exitcode: 1
+stdout:
+stderr: |
+  ack: non-existent-file.txt: No such file or directory
+
+---
+name: Errors with -s
+args: -s search-term non-existent-file.txt
+exitcode: 1
+stdout:
+stderr:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/ack-type.yaml 
new/ack-v3.10.0/t/ack-type.yaml
--- old/ack-v3.9.0/t/ack-type.yaml      1970-01-01 01:00:00.000000000 +0100
+++ new/ack-v3.10.0/t/ack-type.yaml     2026-06-07 18:20:51.000000000 +0200
@@ -0,0 +1,44 @@
+---
+name: --type-set and exclude
+args: >-
+  --ignore-ack-defaults
+  --type-set=cmake:is:CMakeLists.txt
+  --type=nocmake
+  -k -f t/swamp
+exitcode: 1
+stderr: ''
+stdout: ''
+
+---
+name: --type-set and override exclusion
+args: >-
+  --ignore-ack-defaults
+  --type-set=cmake:is:CMakeLists.txt
+  --type=nocmake
+  -t cmake -f t/swamp
+stdout: |
+  t/swamp/CMakeLists.txt
+
+---
+name: --type-set, --type-add, and exclude
+args: >-
+  --ignore-ack-defaults
+  --type-set=cmake:is:CMakeLists.txt
+  --type-add=cmake:ext:cmake
+  --type=nocmake
+  -k -f t/swamp
+exitcode: 1
+stderr: ''
+stdout: ''
+
+---
+name: --type-set, --type-add, and override exclusion
+args: >-
+  --ignore-ack-defaults
+  --type-set=cmake:is:CMakeLists.txt
+  --type-add=cmake:ext:cmake
+  --type=nocmake
+  -t cmake -f t/swamp
+stdout: |
+  t/swamp/CMakeLists.txt
+  t/swamp/stuff.cmake
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/context.yaml 
new/ack-v3.10.0/t/context.yaml
--- old/ack-v3.9.0/t/context.yaml       2025-05-26 21:16:00.000000000 +0200
+++ new/ack-v3.10.0/t/context.yaml      2026-06-07 18:27:51.000000000 +0200
@@ -105,3 +105,15 @@
   This is line 09
   This is line 10
   This is line 11
+
+---
+name: -C with huge context throws
+args: -C 20000|30000 t/text/numbered-text.txt
+exitcode: 1
+stdout: ""
+
+---
+name: -B with huge context throws
+args: -B 20000|30000 t/text/numbered-text.txt
+exitcode: 1
+stdout: ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/file-iterator.t 
new/ack-v3.10.0/t/file-iterator.t
--- old/ack-v3.9.0/t/file-iterator.t    2025-05-26 21:16:00.000000000 +0200
+++ new/ack-v3.10.0/t/file-iterator.t   2026-06-07 18:27:51.000000000 +0200
@@ -34,6 +34,7 @@
 
     sets_match( \@files, [qw(
             t/swamp/0
+            t/swamp/bad-ascii.tar.GZ
             t/swamp/blib/ignore.pm
             t/swamp/blib/ignore.pod
             t/swamp/constitution-100k.pl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/forbidden-options.t 
new/ack-v3.10.0/t/forbidden-options.t
--- old/ack-v3.9.0/t/forbidden-options.t        2023-02-25 21:34:04.000000000 
+0100
+++ new/ack-v3.10.0/t/forbidden-options.t       2026-06-07 18:35:32.000000000 
+0200
@@ -32,7 +32,7 @@
     local $Test::Builder::Level = $Test::Builder::Level + 1;
 
     return subtest subtest_name() => sub {
-        plan tests => 3;
+        plan tests => 4;
 
         my $base_obj = File::Temp->newdir;
         my $base = $base_obj->dirname;
@@ -51,19 +51,20 @@
 
         safe_chdir( $projectdir );
 
-        # All three of these options are illegal in a project .ackrc.
-        for my $option ( qw( match output pager ) ) {
+        # All four of these options are illegal in a project .ackrc.
+        for my $option ( qw( match output pager follow ) ) {
             subtest $option => sub {
                 plan tests => 2;
 
                 # /tmp/x/project/.ackrc
-                _create_ackrc( $projectdir, "--$option=$option" );
+                _create_ackrc( $projectdir, "--$option=$option" ) unless 
'follow' eq $option;
+                _create_ackrc( $projectdir, "--$option"         ) if     
'follow' eq $option;
 
                 # Explicitly pass --env or else the test will ignore .ackrc.
                 my ( $stdout, $stderr ) = run_ack_with_stderr( '-f', '--env' );
 
                 is_empty_array( $stdout, 'No output with the errors' );
-                if ( $option eq 'pager' ) {
+                if ( ($option eq 'pager') || ($option eq 'follow') ) {
                     first_line_like( $stderr, qr/\QOption --$option is 
forbidden in project .ackrc files/, "$option illegal" );
                 }
                 else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/invalid-context.t 
new/ack-v3.10.0/t/invalid-context.t
--- old/ack-v3.9.0/t/invalid-context.t  1970-01-01 01:00:00.000000000 +0100
+++ new/ack-v3.10.0/t/invalid-context.t 2026-06-07 18:35:59.000000000 +0200
@@ -0,0 +1,23 @@
+#!perl
+
+use 5.010;
+use strict;
+use warnings;
+
+use Test::More tests => 5;
+use lib 't';
+use Util;
+
+prep_environment();
+
+
+my ( $stdout, $stderr ) = run_ack_with_stderr( '-C20000' );
+is_empty_array( $stdout, 'No output because of our bad option' );
+
+like( $stderr->[0], qr/ack(?:-standalone)?: Context value 20000 exceeds the 
maximum allowed value of 10000[.]/, 'First line is the specific error' );
+like( $stderr->[1], qr/ack(?:-standalone)?: Invalid option on command line/, 
'Second line is the general error' );
+is( scalar @{$stderr}, 2, 'There are no more lines' );
+
+is( get_rc(), 255, 'Should fail' );
+
+exit 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/naughty-filenames.t 
new/ack-v3.10.0/t/naughty-filenames.t
--- old/ack-v3.9.0/t/naughty-filenames.t        1970-01-01 01:00:00.000000000 
+0100
+++ new/ack-v3.10.0/t/naughty-filenames.t       2026-06-07 18:40:50.000000000 
+0200
@@ -0,0 +1,136 @@
+#!perl
+
+use 5.010;
+use strict;
+use warnings;
+
+use Test::More tests => 1;
+
+use File::Spec ();
+use File::Temp ();
+
+use lib 't';
+use Util;
+
+prep_environment();
+
+# Global:
+# /tmp/x/etc/.ackrc
+# /tmp/x/swamp
+
+my $wd = getcwd_clean();
+
+_test_naughty_ansi_filenames();
+
+exit 0;
+
+# Test project directory
+# ackrc in /tmp/x/project/subdir/{naughtyAnsiFiles}
+#
+sub _test_naughty_ansi_filenames {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+    return subtest subtest_name() => sub {
+        plan tests => 6;
+
+        my $base_obj = File::Temp->newdir;
+        my $base = $base_obj->dirname;
+
+        # /tmp/x/project
+        my $projectdir = File::Spec->catdir( $base, 'project' );
+        safe_mkdir( $projectdir );
+
+        # /tmp/x/project/subdir/
+        my $projectsubdir = File::Spec->catdir( $projectdir, 'subdir' );
+        safe_mkdir( $projectsubdir );
+
+        # These files have evil names, in the sense of ANSI terminal 
manipulation
+        # so are generated and removed rather than shipped in t/
+
+        # /tmp/x/project/subdir/${forged}
+        # (1) Newline injection: filename splits ack output into two lines
+        # original bash equivalent:
+        # # FORGED=$(printf 'real\nFORGED:999:injected_content.pl')
+        # # printf 'foo\n' > "./$FORGED"
+        #
+        my $forged = "real\nFORGED:999:injected_content.pl";
+        my $projectfile = File::Spec->catfile( $projectsubdir, $forged );
+        write_file( $projectfile, "foo FORGED\n" );
+
+        # /tmp/x/project/subdir/${ansi}
+        #  ANSI injection: ESC bytes change terminal appearance
+        # # ANSI=$(printf 'file\033[31mRED\033[0m.pl')
+        # # printf 'foo\n' > "./$ANSI"
+        my $ansi = "file\033[31mRED\033[0m.pl";
+        $projectfile = File::Spec->catfile( $projectsubdir, $ansi );
+        write_file( $projectfile, "foo RED\n" );
+
+        # /tmp/x/project/subdir/normal.pl
+        # # printf 'foo\n' > .//normal.pl
+        $projectfile = File::Spec->catfile( $projectsubdir, 'normal.pl' );
+        write_file( $projectfile, "foo normal\n" );
+
+        safe_chdir( $projectdir );
+
+        # TO VIEW temp dir contents
+        # system('ls', '-alr', 'subdir',);
+
+        my %expect = (
+            RED    => qr{\Qsubdir/file?[31mRED?[0m.pl\E},
+            normal => qr{\Qsubdir/normal.pl\E},
+            FORGED => qr{\Qsubdir/real?FORGED:999:injected_content.pl\E},
+        );
+        for my $name (qw[ RED normal FORGED ]){
+            subtest "5_01_filter_listing_$name" => sub {
+                plan tests => 3;
+                # /tmp/x/project/.ackrc
+                # _create_ackrc( $projectdir, "--$option=$option" ) ???
+
+                # Explicitly pass --env or else the test will ignore .ackrc.
+                my ( $stdout, $stderr ) = run_ack_with_stderr( '-g', '--env', 
$name  );
+
+                # NOT is_empty_array( $stdout, 'No output with the errors' );
+                is (scalar(@$stdout),1, "number of lines correct");
+                like( $stdout->[0], $expect{$name},  "$name listing" );
+
+                is_empty_array( $stderr, 'No errors with output' );
+                # first_line_like( $stderr, qr/\Qsome error message/, "some 
error message" );
+            };
+        } # end for 1
+
+        my %File = (
+                 RED => qq{subdir/file\033\[31mRED\033\[0m.pl},
+                 normal => qq{subdir/normal.pl},
+                 FORGED => qq{subdir/real\nFORGED:injected_content.pl},
+        );
+        %expect = (
+                 RED => qr{subdir/file[?][[]31mRED[?][[]0m[.]pl:1:foo},
+                 normal => qr{subdir/normal.pl:1:foo},
+                 FORGED => 
qr{subdir/real[?]FORGED:999:injected_content[.]pl:1:foo},
+        );
+        for my $name (qw[ RED normal FORGED ]){
+            subtest "5_02_filter_match_$name" => sub {
+                plan tests => 3;
+
+                # /tmp/x/project/.ackrc
+                # _create_ackrc( $projectdir, "--$option=$option" ) ???
+
+                # Explicitly pass --env or else the test will ignore .ackrc.
+                my ( $stdout, $stderr ) = run_ack_with_stderr( '--env', 
'--with-filename', "foo $name" , );
+
+                # NOT is_empty_array( $stdout, 'No output with the errors' );
+                is (scalar(@$stdout),1, "number of lines correct");
+                first_line_like( $stdout, $expect{$name}, "on match, masked 
$name" );
+
+                is_empty_array( $stderr, 'No errors with output' );
+                # first_line_like( $stderr, qr/\Qsome error message/, "some 
error message" );
+
+            };
+        } # end for 2
+
+        # Go back to working directory so the temporary directories can get 
erased.
+        safe_chdir( $wd );
+    };
+}
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ack-v3.9.0/t/no-re-eval.t 
new/ack-v3.10.0/t/no-re-eval.t
--- old/ack-v3.9.0/t/no-re-eval.t       1970-01-01 01:00:00.000000000 +0100
+++ new/ack-v3.10.0/t/no-re-eval.t      2026-06-07 18:42:02.000000000 +0200
@@ -0,0 +1,55 @@
+#!perl
+
+use 5.010;
+use strict;
+use warnings;
+
+use Test::More tests => 1;
+
+use File::Spec ();
+use File::Temp ();
+
+use lib 't';
+use Util;
+
+prep_environment();
+
+# Global:
+# /tmp/x/etc/.ackrc
+# /tmp/x/swamp
+
+my $wd = getcwd_clean();
+
+_test_re_eval();
+
+exit 0;
+
+# Test project directory
+# ackrc in /tmp/x/project/.ackrc
+sub _test_re_eval {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+    return subtest subtest_name() => sub {
+        plan tests => 5;
+
+        # Code assertions are normally permitted in compiled Perl but not 
runtime JIT qr// or match// substitutions.
+        # -M re=eval enables runtime eval-group (?{code}) (??{code}) (*{code}) 
in runtime qr//.
+        # This is unsafe given $PROJECT/.ackrc --type, --ignore options, so 
it's blocked
+        #
+        # TODO Could add tests for --ignore --match --and REs, etc etc, as of 
several files prefaced by `no re 'eval';`
+        # this actually monitors only one for regression.
+        #
+        $ENV{ACK_TEST_MODULE_OPTS}='re=eval'; ## Evil to be thwarted, ask 
Util.pm to prefix evil -Mre=eval for us
+
+        my ( $stdout, $stderr ) = run_ack_with_stderr('-f',
+            q(--type-add=badtype:firstlinematch:/(?{print "hello executing 
code \n"})oops/), ## code injection
+            '--badtype', 't/swamp');
+
+        is_empty_array( $stdout, 'No output with the errors' );  # If not 
fixed, will say 'hello executing code ' repeatedly.
+
+        is(scalar(@$stderr), 3, 'number of errors as expected' );
+        like($stderr->[0], qr/\QEval-group not allowed at runtime,\E/, 
"Eval-group blocked in type RE" );
+        like($stderr->[1], qr/\QUnknown option: badtype\E/, "Unknown option in 
type RE" );
+        like($stderr->[2], qr/\QInvalid option on command line\E/, "invalid 
option reported" );
+    }
+};
Binary files old/ack-v3.9.0/t/swamp/bad-ascii.tar.GZ and 
new/ack-v3.10.0/t/swamp/bad-ascii.tar.GZ differ

Reply via email to