2 # Exercise base{32,64}.
4 # Copyright (C) 2006-2024 Free Software Foundation, Inc.
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <https://www.gnu.org/licenses/>.
21 (my $program_name = $0) =~ s
|.*/||;
23 # Turn off localization of executable's output.
24 @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x
3;
26 # Return the encoding of a string of N 'a's.
30 my %remainder = ( 0 => '', 1 => 'YQ==', 2 => 'YWE=' );
31 return 'YWFh' x
($n / 3) . $remainder{$n % 3};
37 my %remainder = ( 0 => '', 1 => 'ME======', 2 => 'MFQQ====',
38 3 => 'MFQWC===', 4 => 'MFQWCYI=');
39 return 'MFQWCYLB' x
($n / 5) . $remainder{$n % 5};
42 # Function reference to appropriate encoder
45 # An encoded string of length 4KB, using 3K "a"s.
49 # Return a copy of S, with newlines inserted every WIDTH bytes.
50 # Ensure that the result (if not the empty string) is newline-terminated.
54 $s =~ s/(.{$width})/$1\n/g;
55 substr ($s, -1, 1) ne "\n"
65 my $try_help = "Try '$prog --help' for more information.\n";
68 ['empty', {IN
=>''}, {OUT
=>""}],
69 ['inout1', {IN
=>'a'x1
}, {OUT
=>&$enc(1)."\n"}],
70 ['inout2', {IN
=>'a'x2
}, {OUT
=>&$enc(2)."\n"}],
71 ['inout3', {IN
=>'a'x3
}, {OUT
=>&$enc(3)."\n"}],
72 ['inout4', {IN
=>'a'x4
}, {OUT
=>&$enc(4)."\n"}],
73 ['inout5', {IN
=>'a'x5
}, {OUT
=>&$enc(5)."\n"}],
74 ['wrap', '--wrap 0', {IN
=>'a'}, {OUT
=>&$enc(1)}],
75 ['wrap-zero', '--wrap 08', {IN
=>'a'}, {OUT
=>&$enc(1)."\n"}],
76 ['wrap5-39', '--wrap=5', {IN
=>'a' x
39}, {OUT
=>wrap
&$enc(39),5}],
77 ['wrap5-40', '--wrap=5', {IN
=>'a' x
40}, {OUT
=>wrap
&$enc(40),5}],
78 ['wrap5-41', '--wrap=5', {IN
=>'a' x
41}, {OUT
=>wrap
&$enc(41),5}],
79 ['wrap5-42', '--wrap=5', {IN
=>'a' x
42}, {OUT
=>wrap
&$enc(42),5}],
80 ['wrap5-43', '--wrap=5', {IN
=>'a' x
43}, {OUT
=>wrap
&$enc(43),5}],
81 ['wrap5-44', '--wrap=5', {IN
=>'a' x
44}, {OUT
=>wrap
&$enc(44),5}],
82 ['wrap5-45', '--wrap=5', {IN
=>'a' x
45}, {OUT
=>wrap
&$enc(45),5}],
83 ['wrap5-46', '--wrap=5', {IN
=>'a' x
46}, {OUT
=>wrap
&$enc(46),5}],
85 ['wrap-bad-1', '-w0x0', {IN
=>''}, {OUT
=>""},
86 {ERR_SUBST
=> 's/base..:/base..:/'},
87 {ERR
=> "base..: invalid wrap size: '0x0'\n"}, {EXIT
=> 1}],
88 ['wrap-bad-2', '-w1k', {IN
=>''}, {OUT
=>""},
89 {ERR_SUBST
=> 's/base..:/base..:/'},
90 {ERR
=> "base..: invalid wrap size: '1k'\n"}, {EXIT
=> 1}],
91 ['wrap-bad-3', '-w-1', {IN
=>''}, {OUT
=>""},
92 {ERR_SUBST
=> 's/base..:/base..:/'},
93 {ERR
=> "base..: invalid wrap size: '-1'\n"}, {EXIT
=> 1}],
95 ['buf-1', '--decode', {IN
=>&$enc(1)}, {OUT
=>'a' x
1}],
96 ['buf-2', '--decode', {IN
=>&$enc(2)}, {OUT
=>'a' x
2}],
97 ['buf-3', '--decode', {IN
=>&$enc(3)}, {OUT
=>'a' x
3}],
98 ['buf-4', '--decode', {IN
=>&$enc(4)}, {OUT
=>'a' x
4}],
100 ['buf-4k0', '--decode', {IN
=>&$enc(3072+0)}, {OUT
=>'a' x
(3072+0)}],
101 ['buf-4k1', '--decode', {IN
=>&$enc(3072+1)}, {OUT
=>'a' x
(3072+1)}],
102 ['buf-4k2', '--decode', {IN
=>&$enc(3072+2)}, {OUT
=>'a' x
(3072+2)}],
103 ['buf-4k3', '--decode', {IN
=>&$enc(3072+3)}, {OUT
=>'a' x
(3072+3)}],
104 ['buf-4km1','--decode', {IN
=>&$enc(3072-1)}, {OUT
=>'a' x
(3072-1)}],
105 ['buf-4km2','--decode', {IN
=>&$enc(3072-2)}, {OUT
=>'a' x
(3072-2)}],
106 ['buf-4km3','--decode', {IN
=>&$enc(3072-3)}, {OUT
=>'a' x
(3072-3)}],
107 ['buf-4km4','--decode', {IN
=>&$enc(3072-4)}, {OUT
=>'a' x
(3072-4)}],
109 # Exercise the case in which the final base-64 byte is
110 # in a buffer all by itself.
111 ['b4k-1', '--decode', {IN
=>$a3k_nl[1]}, {OUT
=>'a' x
(3072+0)}],
112 ['b4k-2', '--decode', {IN
=>$a3k_nl[2]}, {OUT
=>'a' x
(3072+0)}],
113 ['b4k-3', '--decode', {IN
=>$a3k_nl[3]}, {OUT
=>'a' x
(3072+0)}],
115 ['ext-op1', 'a b', {IN
=>''}, {EXIT
=>1},
116 {ERR
=> "$prog: extra operand 'b'\n" . $try_help}],
117 # Again, with more option arguments
118 ['ext-op2', '-di --wrap=40 a b', {IN
=>''}, {EXIT
=>1},
119 {ERR
=> "$prog: extra operand 'b'\n" . $try_help}],
122 if ($prog eq "base64")
125 ['baddecode', '--decode', {IN
=>'a'}, {OUT
=>""},
126 {ERR_SUBST
=> 's/.*: invalid input//'}, {ERR
=> "\n"}, {EXIT
=> 1}],
127 ['paddecode2', '--decode', {IN
=>'aQ'}, {OUT
=>"i"}],
128 ['paddecode3', '--decode', {IN
=>'Zzw'}, {OUT
=>"g<"}],
129 ['baddecode4', '--decode', {IN
=>'Zz='}, {OUT
=>"g"},
130 {ERR_SUBST
=> 's/.*: invalid input//'}, {ERR
=> "\n"}, {EXIT
=> 1}],
131 ['baddecode5', '--decode', {IN
=>'Z==='}, {OUT
=>""},
132 {ERR_SUBST
=> 's/.*: invalid input//'}, {ERR
=> "\n"}, {EXIT
=> 1}],
133 ['baddecode6', '--decode', {IN
=>'SB=='}, {OUT
=>"H"},
134 {ERR_SUBST
=> 's/.*: invalid input//'}, {ERR
=> "\n"}, {EXIT
=> 1}],
135 ['baddecode7', '--decode', {IN
=>'SGVsbG9='}, {OUT
=>"Hello"},
136 {ERR_SUBST
=> 's/.*: invalid input//'}, {ERR
=> "\n"}, {EXIT
=> 1}]
140 # For each non-failing test, create a --decode test using the
141 # expected output as input. Also, add tests inserting newlines.
143 foreach my $t (@Tests)
149 # If the test has a single option of "--decode", then skip it.
150 !ref $t->[1] && $t->[1] eq '--decode'
155 ref $e && ref $e eq 'HASH'
158 and $exit_val = $e->{EXIT
};
161 if (defined $e->{OUT
})
166 foreach my $i (0..$len)
169 substr ($u, $i, 0) = "\n";
182 push @new, ["d$i-$t->[0]", '--decode', {IN
=> $o}, {OUT
=> $in}];
189 my $save_temps = $ENV{DEBUG
};
190 my $verbose = $ENV{VERBOSE
};
193 foreach my $prog (qw(base32 base64))
195 $enc = $prog eq "base32" ? \
&enc32
: \
&enc64
;
197 # Construct an encoded string of length 4KB, using 3K "a"s.
200 # A few copies, each with different number of newlines at the start.
203 (my $t = $a3k) =~ s/^/"\n"x $k/e;
209 $fail = run_tests
($program_name, $prog, \
@Tests, $save_temps, $verbose);