Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
633 changes: 633 additions & 0 deletions resources/gnu-coreutils-tests/Coreutils.pm

Large diffs are not rendered by default.

39 changes: 39 additions & 0 deletions resources/gnu-coreutils-tests/CuSkip.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package CuSkip;
# Skip a test: emit diag to log and to stderr, and exit 77

# Copyright (C) 2011-2026 Free Software Foundation, Inc.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

use strict;
use warnings;

our $ME = $0 || "<???>";

# Emit a diagnostic both to stderr and to $stderr_fileno_.
# FIXME: don't hard-code that value (9), since it's already defined in init.cfg.
sub skip ($)
{
my ($msg) = @_;
my $stderr_fileno_ = 9;
warn $msg;
open FH, ">&$stderr_fileno_"
or warn "$ME: failed to dup stderr\n";
print FH $msg;
close FH
or warn "$ME: failed to close FD $stderr_fileno_\n";
exit 77;
}

1;
111 changes: 111 additions & 0 deletions resources/gnu-coreutils-tests/CuTmpdir.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package CuTmpdir;
# create, then chdir into a temporary sub-directory

# Copyright (C) 2007-2026 Free Software Foundation, Inc.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

use strict;
use warnings;

use File::Temp;
use File::Find;

our $ME = $0 || "<???>";

my $dir;

sub skip_test($)
{
warn "$ME: skipping test: unsafe working directory name: '$_[0]'\n";
exit 77;
}

sub chmod_1
{
my $name = $_;

# Skip symlinks and non-directories.
-l $name || !-d _
and return;

chmod 0700, $name;
}

sub chmod_tree
{
# When tempdir fails, it croaks, which leaves $dir undefined.
defined $dir
or return;

# Perform the equivalent of find "$dir" -type d -print0|xargs -0 chmod -R 700.
my $options = {untaint => 1, wanted => \&chmod_1};
find ($options, $dir);
}

sub import {
my $prefix = $_[1];

$ME eq '-' && defined $prefix
and $ME = $prefix;

if ($prefix !~ /^\//)
{
eval 'use Cwd';
my $cwd = $@ ? '.' : Cwd::getcwd();
$prefix = "$cwd/$prefix";
}

# Untaint for the upcoming mkdir.
$prefix =~ m!^([-+\@\w./]+)$!
or skip_test $prefix;
$prefix = $1;

my $original_pid = $$;

my $on_sig_remove_tmpdir = sub {
my ($sig) = @_;
if ($$ == $original_pid and defined $dir)
{
chmod_tree;
# Older versions of File::Temp lack this method.
exists &File::Temp::cleanup
and &File::Temp::cleanup;
}
$SIG{$sig} = 'DEFAULT';
kill $sig, $$;
};

foreach my $sig (qw (INT TERM HUP))
{
$SIG{$sig} = $on_sig_remove_tmpdir;
}

$dir = File::Temp::tempdir("$prefix.tmp-XXXX", CLEANUP => 1 );
chdir $dir
or warn "$ME: failed to chdir to $dir: $!\n";
}

END {
# Move cwd out of the directory we're about to remove.
# This is required on some systems, and by some versions of File::Temp.
chdir '..'
or warn "$ME: failed to chdir to .. from $dir: $!\n";

my $saved_errno = $?;
chmod_tree;
$? = $saved_errno;
}

1;
20 changes: 20 additions & 0 deletions resources/gnu-coreutils-tests/GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Provide a compatibility layer so that the commands used before the
# conversion of tests/ to non-recursive make still work. To do that, we
# must rerun the "make check" from the parent, and with tests/ prefixed
# onto any TESTS values. The SUBDIRS=. is to prevent the top-level check
# rules from descending into e.g., gnulib-test/.

.PHONY: all
all:
@echo 'tests/GNUmakefile: did you mean to make "check"?' 1>&2
@exit 1

ifeq ($(TESTS),)
tests =
else
tests = TESTS=$(addprefix tests/,$(TESTS))
endif

.PHONY: check
check:
cd .. && $(MAKE) $@ $(tests) SUBDIRS=.
222 changes: 222 additions & 0 deletions resources/gnu-coreutils-tests/basenc/base64.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
#!/usr/bin/perl
# Exercise base{32,64}.

# Copyright (C) 2006-2026 Free Software Foundation, Inc.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

use strict;

(my $program_name = $0) =~ s|.*/||;

# Turn off localization of executable's output.
@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;

# Return the encoding of a string of N 'a's.
sub enc64($)
{
my ($n) = @_;
my %remainder = ( 0 => '', 1 => 'YQ==', 2 => 'YWE=' );
return 'YWFh' x ($n / 3) . $remainder{$n % 3};
}

sub enc32($)
{
my ($n) = @_;
my %remainder = ( 0 => '', 1 => 'ME======', 2 => 'MFQQ====',
3 => 'MFQWC===', 4 => 'MFQWCYI=');
return 'MFQWCYLB' x ($n / 5) . $remainder{$n % 5};
}

# Function reference to appropriate encoder
my $enc;

# An encoded string of length 4KB, using 3K "a"s.
my $a3k;
my @a3k_nl;

# Return a copy of S, with newlines inserted every WIDTH bytes.
# Ensure that the result (if not the empty string) is newline-terminated.
sub wrap($$)
{
my ($s, $width) = @_;
$s =~ s/(.{$width})/$1\n/g;
substr ($s, -1, 1) ne "\n"
and $s .= "\n";
return $s;
}

my @Tests;

sub gen_tests($)
{
my ($prog) = @_;
my $try_help = "Try '$prog --help' for more information.\n";
@Tests=
(
['empty', {IN=>''}, {OUT=>""}],
['inout1', {IN=>'a'x1}, {OUT=>&$enc(1)."\n"}],
['inout2', {IN=>'a'x2}, {OUT=>&$enc(2)."\n"}],
['inout3', {IN=>'a'x3}, {OUT=>&$enc(3)."\n"}],
['inout4', {IN=>'a'x4}, {OUT=>&$enc(4)."\n"}],
['inout5', {IN=>'a'x5}, {OUT=>&$enc(5)."\n"}],
['wrap', '--wrap 0', {IN=>'a'}, {OUT=>&$enc(1)}],
['wrap-zero', '--wrap 08', {IN=>'a'}, {OUT=>&$enc(1)."\n"}],
['wrap5-39', '--wrap=5', {IN=>'a' x 39}, {OUT=>wrap &$enc(39),5}],
['wrap5-40', '--wrap=5', {IN=>'a' x 40}, {OUT=>wrap &$enc(40),5}],
['wrap5-41', '--wrap=5', {IN=>'a' x 41}, {OUT=>wrap &$enc(41),5}],
['wrap5-42', '--wrap=5', {IN=>'a' x 42}, {OUT=>wrap &$enc(42),5}],
['wrap5-43', '--wrap=5', {IN=>'a' x 43}, {OUT=>wrap &$enc(43),5}],
['wrap5-44', '--wrap=5', {IN=>'a' x 44}, {OUT=>wrap &$enc(44),5}],
['wrap5-45', '--wrap=5', {IN=>'a' x 45}, {OUT=>wrap &$enc(45),5}],
['wrap5-46', '--wrap=5', {IN=>'a' x 46}, {OUT=>wrap &$enc(46),5}],

['wrap-bad-1', '-w0x0', {IN=>''}, {OUT=>""},
{ERR_SUBST => 's/base..:/base..:/'},
{ERR => "base..: invalid wrap size: '0x0'\n"}, {EXIT => 1}],
['wrap-bad-2', '-w1k', {IN=>''}, {OUT=>""},
{ERR_SUBST => 's/base..:/base..:/'},
{ERR => "base..: invalid wrap size: '1k'\n"}, {EXIT => 1}],
['wrap-bad-3', '-w-1', {IN=>''}, {OUT=>""},
{ERR_SUBST => 's/base..:/base..:/'},
{ERR => "base..: invalid wrap size: '-1'\n"}, {EXIT => 1}],

['buf-1', '--decode', {IN=>&$enc(1)}, {OUT=>'a' x 1}],
['buf-2', '--decode', {IN=>&$enc(2)}, {OUT=>'a' x 2}],
['buf-3', '--decode', {IN=>&$enc(3)}, {OUT=>'a' x 3}],
['buf-4', '--decode', {IN=>&$enc(4)}, {OUT=>'a' x 4}],
# 4KB worth of input.
['buf-4k0', '--decode', {IN=>&$enc(3072+0)}, {OUT=>'a' x (3072+0)}],
['buf-4k1', '--decode', {IN=>&$enc(3072+1)}, {OUT=>'a' x (3072+1)}],
['buf-4k2', '--decode', {IN=>&$enc(3072+2)}, {OUT=>'a' x (3072+2)}],
['buf-4k3', '--decode', {IN=>&$enc(3072+3)}, {OUT=>'a' x (3072+3)}],
['buf-4km1','--decode', {IN=>&$enc(3072-1)}, {OUT=>'a' x (3072-1)}],
['buf-4km2','--decode', {IN=>&$enc(3072-2)}, {OUT=>'a' x (3072-2)}],
['buf-4km3','--decode', {IN=>&$enc(3072-3)}, {OUT=>'a' x (3072-3)}],
['buf-4km4','--decode', {IN=>&$enc(3072-4)}, {OUT=>'a' x (3072-4)}],

# Exercise the case in which the final base-64 byte is
# in a buffer all by itself.
['b4k-1', '--decode', {IN=>$a3k_nl[1]}, {OUT=>'a' x (3072+0)}],
['b4k-2', '--decode', {IN=>$a3k_nl[2]}, {OUT=>'a' x (3072+0)}],
['b4k-3', '--decode', {IN=>$a3k_nl[3]}, {OUT=>'a' x (3072+0)}],

['ext-op1', 'a b', {IN=>''}, {EXIT=>1},
{ERR => "$prog: extra operand 'b'\n" . $try_help}],
# Again, with more option arguments
['ext-op2', '-di --wrap=40 a b', {IN=>''}, {EXIT=>1},
{ERR => "$prog: extra operand 'b'\n" . $try_help}],
);

if ($prog eq "base64")
{
push @Tests, (
['paddec1', '--decode', {IN=>'aQ'}, {OUT=>"i"}],
['paddec2', '--decode', {IN=>'Zzw'}, {OUT=>"g<"}],
['paddec3', '--decode', {IN=>'MTIzNA==MTIzNA'}, {OUT=>"12341234"}],
['paddec4', '--decode', {IN=>"MTIzNA==\nMTIzNA"}, {OUT=>"12341234"}],
['baddecode', '--decode', {IN=>'a'}, {OUT=>""},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
['baddecode4', '--decode', {IN=>'Zz='}, {OUT=>"g"},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
['baddecode5', '--decode', {IN=>'Z==='}, {OUT=>""},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
['baddecode6', '--decode', {IN=>'SB=='}, {OUT=>"H"},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
['baddecode7', '--decode', {IN=>'SGVsbG9='}, {OUT=>"Hello"},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
['baddecode8', '--decode', {IN=>'MTIzNA='}, {OUT=>"1234"},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
['baddecode9', '--decode', {IN=>"MTIzNA=\n"}, {OUT=>"1234"},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}]
);
}

# For each non-failing test, create a --decode test using the
# expected output as input. Also, add tests inserting newlines.
my @new;
foreach my $t (@Tests)
{
my $exit_val;
my $in;
my @out;

# If the test has a single option of "--decode", then skip it.
!ref $t->[1] && $t->[1] eq '--decode'
and next;

foreach my $e (@$t)
{
ref $e && ref $e eq 'HASH'
or next;
defined $e->{EXIT}
and $exit_val = $e->{EXIT};
defined $e->{IN}
and $in = $e->{IN};
if (defined $e->{OUT})
{
my $t = $e->{OUT};
push @out, $t;
my $len = length $t;
foreach my $i (0..$len)
{
my $u = $t;
substr ($u, $i, 0) = "\n";
push @out, $u;
10 <= $i
and last;
}
}
}
$exit_val
and next;

my $i = 0;
foreach my $o (@out)
{
push @new, ["d$i-$t->[0]", '--decode', {IN => $o}, {OUT => $in}];
++$i;
}
}
push @Tests, @new;
}

my $save_temps = $ENV{DEBUG};
my $verbose = $ENV{VERBOSE};

my $fail = 0;
foreach my $prog (qw(base32 base64))
{
$enc = $prog eq "base32" ? \&enc32 : \&enc64;

# Construct an encoded string of length 4KB, using 3K "a"s.
$a3k = &$enc(3072);
@a3k_nl = ();
# A few copies, each with different number of newlines at the start.
for my $k (0..3)
{
(my $t = $a3k) =~ s/^/"\n"x $k/e;
push @a3k_nl, $t;
}

gen_tests($prog);

$fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose);
if ($fail != 0)
{
last;
}
}

exit $fail;
Loading