1
0
mirror of https://git.savannah.gnu.org/git/coreutils.git synced 2025-07-02 21:22:27 +03:00

base32: A new program similar to base64

Suggested in https://bugzilla.redhat.com/1250113

* AUTHORS: Add base32.
* THANKS.in: Add suggester.
* README: Reference the new program.
* NEWS: Mention the new program.
* src/.gitignore: Ignore the new binary.
* bootstrap.conf: Reference the gnulib base32 module.
* build-aux/gen-lists-of-programs.sh: Add base32.
* man/base32.x: A new template.
* man/.gitignore: Ignore the new man page.
* man/local.mk: Reference the new man page.
* doc/coreutils.texi (base32 invocation): Document the new command.
* src/local.mk: Adjust to build base32 based on base64.c.
* src/base64.c: Parameterize to use the correct headers,
functions and buffer sizes, depending on which binary
is being built.
* tests/misc/base64.pl: Adjust to test both base32 and base64.
* tests/misc/tty-eof.pl: Add base32 as a program that
accepts input on stdin without any options specified.
* scripts/git-hooks/commit-msg: Add base32 to the template.
This commit is contained in:
Pádraig Brady
2015-08-05 10:28:36 +02:00
parent affc8e8087
commit 89c517d9e2
16 changed files with 217 additions and 108 deletions

View File

@ -2,6 +2,7 @@ Here are the names of the programs in this package,
each followed by the name(s) of its author(s). each followed by the name(s) of its author(s).
arch: David MacKenzie, Karel Zak arch: David MacKenzie, Karel Zak
base32: Simon Josefsson
base64: Simon Josefsson base64: Simon Josefsson
basename: David MacKenzie basename: David MacKenzie
cat: Torbjörn Granlund, Richard M. Stallman cat: Torbjörn Granlund, Richard M. Stallman

5
NEWS
View File

@ -7,6 +7,11 @@ GNU coreutils NEWS -*- outline -*-
shred again uses defined patterns for all iteration counts. shred again uses defined patterns for all iteration counts.
[bug introduced in coreutils-5.93] [bug introduced in coreutils-5.93]
** New commands
base32 is added to complement the existing base64 command,
and encodes and decodes printable text as per RFC 4648.
* Noteworthy changes in release 8.24 (2015-07-03) [stable] * Noteworthy changes in release 8.24 (2015-07-03) [stable]

2
README
View File

@ -7,7 +7,7 @@ arbitrary limits.
The programs that can be built with this package are: The programs that can be built with this package are:
[ arch base64 basename cat chcon chgrp chmod chown chroot cksum comm [ arch base32 base64 basename cat chcon chgrp chmod chown chroot cksum comm
coreutils cp csplit cut date dd df dir dircolors dirname du echo env coreutils cp csplit cut date dd df dir dircolors dirname du echo env
expand expr factor false fmt fold groups head hostid hostname id install expand expr factor false fmt fold groups head hostid hostname id install
join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl

View File

@ -469,6 +469,7 @@ Nicolas François nicolas.francois@centraliens.net
Niklas Edmundsson nikke@acc.umu.se Niklas Edmundsson nikke@acc.umu.se
Nikola Milutinovic Nikola.Milutinovic@ev.co.yu Nikola Milutinovic Nikola.Milutinovic@ev.co.yu
Nikolaus Rath Nikolaus@rath.org Nikolaus Rath Nikolaus@rath.org
Nikos Mavrogiannopoulos nmav@redhat.com
Nima Nikzad nnikzad@ucla.edu Nima Nikzad nnikzad@ucla.edu
Noah Friedman friedman@splode.com Noah Friedman friedman@splode.com
Noel Cragg noel@red-bean.com Noel Cragg noel@red-bean.com

View File

@ -37,6 +37,7 @@ gnulib_modules="
linked-list linked-list
backupfile backupfile
base64 base64
base32
buffer-lcm buffer-lcm
c-strcase c-strcase
c-strtod c-strtod

View File

@ -42,6 +42,7 @@ build_if_possible_progs='
normal_progs=' normal_progs='
[ [
base64 base64
base32
basename basename
cat cat
chcon chcon

View File

@ -37,6 +37,7 @@
@dircategory Individual utilities @dircategory Individual utilities
@direntry @direntry
* arch: (coreutils)arch invocation. Print machine hardware name. * arch: (coreutils)arch invocation. Print machine hardware name.
* base32: (coreutils)base32 invocation. Base32 encode/decode data.
* base64: (coreutils)base64 invocation. Base64 encode/decode data. * base64: (coreutils)base64 invocation. Base64 encode/decode data.
* basename: (coreutils)basename invocation. Strip directory and suffix. * basename: (coreutils)basename invocation. Strip directory and suffix.
* cat: (coreutils)cat invocation. Concatenate and write files. * cat: (coreutils)cat invocation. Concatenate and write files.
@ -183,7 +184,7 @@ Free Documentation License''.
@menu @menu
* Introduction:: Caveats, overview, and authors * Introduction:: Caveats, overview, and authors
* Common options:: Common options * Common options:: Common options
* Output of entire files:: cat tac nl od base64 * Output of entire files:: cat tac nl od base32 base64
* Formatting file contents:: fmt pr fold * Formatting file contents:: fmt pr fold
* Output of parts of files:: head tail split csplit * Output of parts of files:: head tail split csplit
* Summarizing files:: wc sum cksum md5sum sha1sum sha2 * Summarizing files:: wc sum cksum md5sum sha1sum sha2
@ -238,6 +239,7 @@ Output of entire files
* tac invocation:: Concatenate and write files in reverse * tac invocation:: Concatenate and write files in reverse
* nl invocation:: Number lines and write files * nl invocation:: Number lines and write files
* od invocation:: Write files in octal or other formats * od invocation:: Write files in octal or other formats
* base32 invocation:: Transform data into printable data
* base64 invocation:: Transform data into printable data * base64 invocation:: Transform data into printable data
Formatting file contents Formatting file contents
@ -1551,6 +1553,7 @@ in some way.
* tac invocation:: Concatenate and write files in reverse. * tac invocation:: Concatenate and write files in reverse.
* nl invocation:: Number lines and write files. * nl invocation:: Number lines and write files.
* od invocation:: Write files in octal or other formats. * od invocation:: Write files in octal or other formats.
* base32 invocation:: Transform data into printable data.
* base64 invocation:: Transform data into printable data. * base64 invocation:: Transform data into printable data.
@end menu @end menu
@ -2138,6 +2141,20 @@ address.
@exitstatus @exitstatus
@node base32 invocation
@section @command{base32}: Transform data into printable data
@pindex base32
@cindex base32 encoding
@command{base32} transforms data read from a file, or standard input,
into (or from) base32 encoded form. The base32 encoded form uses
printable ASCII characters to represent binary data.
The usage and options of this command are precisely the
same as for @command{base64}. @xref{base64 invocation}.
@node base64 invocation @node base64 invocation
@section @command{base64}: Transform data into printable data @section @command{base64}: Transform data into printable data
@ -2155,6 +2172,7 @@ base64 --decode [@var{option}]@dots{} [@var{file}]
@end smallexample @end smallexample
The base64 encoding expands data to roughly 133% of the original. The base64 encoding expands data to roughly 133% of the original.
The base32 encoding expands data to roughly 160% of the original.
The format conforms to The format conforms to
@uref{ftp://ftp.rfc-editor.org/in-notes/rfc4648.txt, RFC 4648}. @uref{ftp://ftp.rfc-editor.org/in-notes/rfc4648.txt, RFC 4648}.

1
man/.gitignore vendored
View File

@ -1,5 +1,6 @@
Makefile Makefile
Makefile.in Makefile.in
base32.1
base64.1 base64.1
basename.1 basename.1
cat.1 cat.1

4
man/base32.x Normal file
View File

@ -0,0 +1,4 @@
[NAME]
base32 \- base32 encode/decode data and print to standard output
[DESCRIPTION]
.\" Add any additional description here

View File

@ -60,6 +60,7 @@ man/arch.1: src/uname$(EXEEXT)
man/install.1: src/ginstall$(EXEEXT) man/install.1: src/ginstall$(EXEEXT)
man/test.1: src/[$(EXEEXT) man/test.1: src/[$(EXEEXT)
man/base32.1: src/base32$(EXEEXT)
man/base64.1: src/base64$(EXEEXT) man/base64.1: src/base64$(EXEEXT)
man/basename.1: src/basename$(EXEEXT) man/basename.1: src/basename$(EXEEXT)
man/cat.1: src/cat$(EXEEXT) man/cat.1: src/cat$(EXEEXT)

View File

@ -14,7 +14,7 @@ $editor = "vi" if $? != 0 or $editor =~ /^\s*\z/;
# Keywords allowed before the colon on the first line of a commit message: # Keywords allowed before the colon on the first line of a commit message:
# program names and a few general category names. # program names and a few general category names.
my @valid = qw( my @valid = qw(
arch base64 basename cat chcon chgrp chmod chown chroot cksum comm arch base32 base64 basename cat chcon chgrp chmod chown chroot cksum comm
cp csplit cut date dd df dir dircolors dirname du echo env expand cp csplit cut date dd df dir dircolors dirname du echo env expand
expr factor false fmt fold groups head hostid hostname id install expr factor false fmt fold groups head hostid hostname id install
join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp

1
src/.gitignore vendored
View File

@ -2,6 +2,7 @@
/.dirstamp /.dirstamp
\[ \[
arch arch
base32
base64 base64
basename basename
cat cat

View File

@ -32,13 +32,17 @@
#include "quotearg.h" #include "quotearg.h"
#include "xfreopen.h" #include "xfreopen.h"
#include "base64.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "base64"
#define AUTHORS proper_name ("Simon Josefsson") #define AUTHORS proper_name ("Simon Josefsson")
#if BASE_TYPE == 32
# include "base32.h"
# define PROGRAM_NAME "base32"
#else
# include "base64.h"
# define PROGRAM_NAME "base64"
#endif
static struct option const long_options[] = static struct option const long_options[] =
{ {
{"decode", no_argument, 0, 'd'}, {"decode", no_argument, 0, 'd'},
@ -59,8 +63,8 @@ usage (int status)
{ {
printf (_("\ printf (_("\
Usage: %s [OPTION]... [FILE]\n\ Usage: %s [OPTION]... [FILE]\n\
Base64 encode or decode FILE, or standard input, to standard output.\n\ Base%d encode or decode FILE, or standard input, to standard output.\n\
"), program_name); "), program_name, BASE_TYPE);
emit_stdin_note (); emit_stdin_note ();
emit_mandatory_arg_note (); emit_mandatory_arg_note ();
@ -74,13 +78,13 @@ Base64 encode or decode FILE, or standard input, to standard output.\n\
"), stdout); "), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\ printf (_("\
\n\ \n\
The data are encoded as described for the base64 alphabet in RFC 3548.\n\ The data are encoded as described for the %s alphabet in RFC 4648.\n\
When decoding, the input may contain newlines in addition to the bytes of\n\ When decoding, the input may contain newlines in addition to the bytes of\n\
the formal base64 alphabet. Use --ignore-garbage to attempt to recover\n\ the formal %s alphabet. Use --ignore-garbage to attempt to recover\n\
from any other non-alphabet bytes in the encoded stream.\n"), from any other non-alphabet bytes in the encoded stream.\n"),
stdout); PROGRAM_NAME, PROGRAM_NAME);
emit_ancillary_info (PROGRAM_NAME); emit_ancillary_info (PROGRAM_NAME);
} }
@ -88,15 +92,38 @@ from any other non-alphabet bytes in the encoded stream.\n"),
} }
#define ENC_BLOCKSIZE (1024*3*10) #define ENC_BLOCKSIZE (1024*3*10)
#define ENC_B64BLOCKSIZE BASE64_LENGTH (ENC_BLOCKSIZE)
#if BASE_TYPE == 32
# define BASE_LENGTH BASE32_LENGTH
/* Note that increasing this may decrease performance if --ignore-garbage /* Note that increasing this may decrease performance if --ignore-garbage
is used, because of the memmove operation below. */ is used, because of the memmove operation below. */
#define DEC_BLOCKSIZE (1024*3) # define DEC_BLOCKSIZE (1024*5)
#define DEC_B64BLOCKSIZE BASE64_LENGTH (DEC_BLOCKSIZE)
/* Ensure that BLOCKSIZE is a multiple of 5 and 8. */
verify (ENC_BLOCKSIZE % 40 == 0); /* So padding chars only on last block. */
verify (DEC_BLOCKSIZE % 40 == 0); /* So complete encoded blocks are used. */
# define base_encode base32_encode
# define base_decode_context base32_decode_context
# define base_decode_ctx_init base32_decode_ctx_init
# define base_decode_ctx base32_decode_ctx
# define isbase isbase32
#else
# define BASE_LENGTH BASE64_LENGTH
/* Note that increasing this may decrease performance if --ignore-garbage
is used, because of the memmove operation below. */
# define DEC_BLOCKSIZE (1024*3)
/* Ensure that BLOCKSIZE is a multiple of 3 and 4. */ /* Ensure that BLOCKSIZE is a multiple of 3 and 4. */
verify (ENC_BLOCKSIZE % 12 == 0); verify (ENC_BLOCKSIZE % 12 == 0); /* So padding chars only on last block. */
verify (DEC_BLOCKSIZE % 12 == 0); verify (DEC_BLOCKSIZE % 12 == 0); /* So complete encoded blocks are used. */
# define base_encode base64_encode
# define base_decode_context base64_decode_context
# define base_decode_ctx_init base64_decode_ctx_init
# define base_decode_ctx base64_decode_ctx
# define isbase isbase64
#endif
static void static void
wrap_write (const char *buffer, size_t len, wrap_write (const char *buffer, size_t len,
@ -138,7 +165,7 @@ do_encode (FILE *in, FILE *out, uintmax_t wrap_column)
{ {
size_t current_column = 0; size_t current_column = 0;
char inbuf[ENC_BLOCKSIZE]; char inbuf[ENC_BLOCKSIZE];
char outbuf[ENC_B64BLOCKSIZE]; char outbuf[BASE_LENGTH (ENC_BLOCKSIZE)];
size_t sum; size_t sum;
do do
@ -155,11 +182,11 @@ do_encode (FILE *in, FILE *out, uintmax_t wrap_column)
if (sum > 0) if (sum > 0)
{ {
/* Process input one block at a time. Note that ENC_BLOCKSIZE % /* Process input one block at a time. Note that ENC_BLOCKSIZE
3 == 0, so that no base64 pads will appear in output. */ is sized so that no pad chars will appear in output. */
base64_encode (inbuf, sum, outbuf, BASE64_LENGTH (sum)); base_encode (inbuf, sum, outbuf, BASE_LENGTH (sum));
wrap_write (outbuf, BASE64_LENGTH (sum), wrap_column, wrap_write (outbuf, BASE_LENGTH (sum), wrap_column,
&current_column, out); &current_column, out);
} }
} }
@ -176,12 +203,12 @@ do_encode (FILE *in, FILE *out, uintmax_t wrap_column)
static void static void
do_decode (FILE *in, FILE *out, bool ignore_garbage) do_decode (FILE *in, FILE *out, bool ignore_garbage)
{ {
char inbuf[DEC_B64BLOCKSIZE]; char inbuf[BASE_LENGTH (DEC_BLOCKSIZE)];
char outbuf[DEC_BLOCKSIZE]; char outbuf[DEC_BLOCKSIZE];
size_t sum; size_t sum;
struct base64_decode_context ctx; struct base_decode_context ctx;
base64_decode_ctx_init (&ctx); base_decode_ctx_init (&ctx);
do do
{ {
@ -192,13 +219,13 @@ do_decode (FILE *in, FILE *out, bool ignore_garbage)
sum = 0; sum = 0;
do do
{ {
n = fread (inbuf + sum, 1, DEC_B64BLOCKSIZE - sum, in); n = fread (inbuf + sum, 1, BASE_LENGTH (DEC_BLOCKSIZE) - sum, in);
if (ignore_garbage) if (ignore_garbage)
{ {
size_t i; size_t i;
for (i = 0; n > 0 && i < n;) for (i = 0; n > 0 && i < n;)
if (isbase64 (inbuf[sum + i]) || inbuf[sum + i] == '=') if (isbase (inbuf[sum + i]) || inbuf[sum + i] == '=')
i++; i++;
else else
memmove (inbuf + sum + i, inbuf + sum + i + 1, --n - i); memmove (inbuf + sum + i, inbuf + sum + i + 1, --n - i);
@ -209,7 +236,7 @@ do_decode (FILE *in, FILE *out, bool ignore_garbage)
if (ferror (in)) if (ferror (in))
error (EXIT_FAILURE, errno, _("read error")); error (EXIT_FAILURE, errno, _("read error"));
} }
while (sum < DEC_B64BLOCKSIZE && !feof (in)); while (sum < BASE_LENGTH (DEC_BLOCKSIZE) && !feof (in));
/* The following "loop" is usually iterated just once. /* The following "loop" is usually iterated just once.
However, when it processes the final input buffer, we want However, when it processes the final input buffer, we want
@ -220,7 +247,7 @@ do_decode (FILE *in, FILE *out, bool ignore_garbage)
if (k == 1 && ctx.i == 0) if (k == 1 && ctx.i == 0)
break; break;
n = DEC_BLOCKSIZE; n = DEC_BLOCKSIZE;
ok = base64_decode_ctx (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n); ok = base_decode_ctx (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n);
if (fwrite (outbuf, 1, n, out) < n) if (fwrite (outbuf, 1, n, out) < n)
error (EXIT_FAILURE, errno, _("write error")); error (EXIT_FAILURE, errno, _("write error"));
@ -241,9 +268,9 @@ main (int argc, char **argv)
/* True if --decode has been given and we should decode data. */ /* True if --decode has been given and we should decode data. */
bool decode = false; bool decode = false;
/* True if we should ignore non-base64-alphabetic characters. */ /* True if we should ignore non-base-alphabetic characters. */
bool ignore_garbage = false; bool ignore_garbage = false;
/* Wrap encoded base64 data around the 76:th column, by default. */ /* Wrap encoded data around the 76:th column, by default. */
uintmax_t wrap_column = 76; uintmax_t wrap_column = 76;
initialize_main (&argc, &argv); initialize_main (&argc, &argv);

View File

@ -94,6 +94,7 @@ LDADD = src/libver.a lib/libcoreutils.a $(LIBINTL) lib/libcoreutils.a
# See [ below. # See [ below.
src_arch_LDADD = $(LDADD) src_arch_LDADD = $(LDADD)
src_base64_LDADD = $(LDADD) src_base64_LDADD = $(LDADD)
src_base32_LDADD = $(LDADD)
src_basename_LDADD = $(LDADD) src_basename_LDADD = $(LDADD)
src_cat_LDADD = $(LDADD) src_cat_LDADD = $(LDADD)
src_chcon_LDADD = $(LDADD) src_chcon_LDADD = $(LDADD)
@ -398,6 +399,10 @@ src_sha384sum_CPPFLAGS = -DHASH_ALGO_SHA384=1 $(AM_CPPFLAGS)
src_sha512sum_SOURCES = src/md5sum.c src_sha512sum_SOURCES = src/md5sum.c
src_sha512sum_CPPFLAGS = -DHASH_ALGO_SHA512=1 $(AM_CPPFLAGS) src_sha512sum_CPPFLAGS = -DHASH_ALGO_SHA512=1 $(AM_CPPFLAGS)
src_base64_CPPFLAGS = -DBASE_TYPE=64 $(AM_CPPFLAGS)
src_base32_SOURCES = src/base64.c
src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS)
src_ginstall_CPPFLAGS = -DENABLE_MATCHPATHCON=1 $(AM_CPPFLAGS) src_ginstall_CPPFLAGS = -DENABLE_MATCHPATHCON=1 $(AM_CPPFLAGS)
# Ensure we don't link against libcoreutils.a as that lib is # Ensure we don't link against libcoreutils.a as that lib is

View File

@ -1,5 +1,5 @@
#!/usr/bin/perl #!/usr/bin/perl
# Exercise base64. # Exercise base{32,64}.
# Copyright (C) 2006-2015 Free Software Foundation, Inc. # Copyright (C) 2006-2015 Free Software Foundation, Inc.
@ -24,22 +24,27 @@ use strict;
@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
# Return the encoding of a string of N 'a's. # Return the encoding of a string of N 'a's.
sub enc($) sub enc64($)
{ {
my ($n) = @_; my ($n) = @_;
my %remainder = ( 0 => '', 1 => 'YQ==', 2 => 'YWE=' ); my %remainder = ( 0 => '', 1 => 'YQ==', 2 => 'YWE=' );
return 'YWFh' x ($n / 3) . $remainder{$n % 3}; return 'YWFh' x ($n / 3) . $remainder{$n % 3};
} }
# Construct an encoded string of length 4KB, using 3K "a"s. sub enc32($)
my $a3k = enc 3072; {
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; my @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;
}
# Return a copy of S, with newlines inserted every WIDTH bytes. # Return a copy of S, with newlines inserted every WIDTH bytes.
# Ensure that the result (if not the empty string) is newline-terminated. # Ensure that the result (if not the empty string) is newline-terminated.
@ -52,40 +57,53 @@ sub wrap($$)
return $s; return $s;
} }
my @Tests = my @Tests;
sub gen_tests($)
{
my ($prog) = @_;
@Tests=
( (
['empty', {IN=>''}, {OUT=>""}], ['empty', {IN=>''}, {OUT=>""}],
['inout', {IN=>'a'}, {OUT=>"YQ==\n"}], ['inout1', {IN=>'a'x1}, {OUT=>&$enc(1)."\n"}],
['wrap', '--wrap 0', {IN=>'foo'}, {OUT=>'Zm9v'}], ['inout2', {IN=>'a'x2}, {OUT=>&$enc(2)."\n"}],
['wrap5-39', '--wrap=5', {IN=>'a' x 39}, {OUT=>wrap enc(39),5}], ['inout3', {IN=>'a'x3}, {OUT=>&$enc(3)."\n"}],
['wrap5-40', '--wrap=5', {IN=>'a' x 40}, {OUT=>wrap enc(40),5}], ['inout4', {IN=>'a'x4}, {OUT=>&$enc(4)."\n"}],
['wrap5-41', '--wrap=5', {IN=>'a' x 41}, {OUT=>wrap enc(41),5}], ['inout5', {IN=>'a'x5}, {OUT=>&$enc(5)."\n"}],
['wrap5-42', '--wrap=5', {IN=>'a' x 42}, {OUT=>wrap enc(42),5}], ['wrap', '--wrap 0', {IN=>'a'}, {OUT=>&$enc(1)}],
['wrap5-43', '--wrap=5', {IN=>'a' x 43}, {OUT=>wrap enc(43),5}], ['wrap5-39', '--wrap=5', {IN=>'a' x 39}, {OUT=>wrap &$enc(39),5}],
['wrap5-44', '--wrap=5', {IN=>'a' x 44}, {OUT=>wrap enc(44),5}], ['wrap5-40', '--wrap=5', {IN=>'a' x 40}, {OUT=>wrap &$enc(40),5}],
['wrap5-45', '--wrap=5', {IN=>'a' x 45}, {OUT=>wrap enc(45),5}], ['wrap5-41', '--wrap=5', {IN=>'a' x 41}, {OUT=>wrap &$enc(41),5}],
['wrap5-46', '--wrap=5', {IN=>'a' x 46}, {OUT=>wrap enc(46),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}],
['buf-1', '--decode', {IN=>enc 1}, {OUT=>'a' x 1}], ['buf-1', '--decode', {IN=>&$enc(1)}, {OUT=>'a' x 1}],
['buf-2', '--decode', {IN=>enc 2}, {OUT=>'a' x 2}], ['buf-2', '--decode', {IN=>&$enc(2)}, {OUT=>'a' x 2}],
['buf-3', '--decode', {IN=>enc 3}, {OUT=>'a' x 3}], ['buf-3', '--decode', {IN=>&$enc(3)}, {OUT=>'a' x 3}],
['buf-4', '--decode', {IN=>enc 4}, {OUT=>'a' x 4}], ['buf-4', '--decode', {IN=>&$enc(4)}, {OUT=>'a' x 4}],
# 4KB worth of input. # 4KB worth of input.
['buf-4k0', '--decode', {IN=>enc 3072+0}, {OUT=>'a' x (3072+0)}], ['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-4k1', '--decode', {IN=>&$enc(3072+1)}, {OUT=>'a' x (3072+1)}],
['buf-4k2', '--decode', {IN=>enc 3072+2}, {OUT=>'a' x (3072+2)}], ['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-4k3', '--decode', {IN=>&$enc(3072+3)}, {OUT=>'a' x (3072+3)}],
['buf-4km1','--decode', {IN=>enc 3072-1}, {OUT=>'a' x (3072-1)}], ['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-4km2','--decode', {IN=>&$enc(3072-2)}, {OUT=>'a' x (3072-2)}],
['buf-4km3','--decode', {IN=>enc 3072-3}, {OUT=>'a' x (3072-3)}], ['buf-4km3','--decode', {IN=>&$enc(3072-3)}, {OUT=>'a' x (3072-3)}],
['buf-4km4','--decode', {IN=>enc 3072-4}, {OUT=>'a' x (3072-4)}], ['buf-4km4','--decode', {IN=>&$enc(3072-4)}, {OUT=>'a' x (3072-4)}],
# Exercise the case in which the final base-64 byte is # Exercise the case in which the final base-64 byte is
# in a buffer all by itself. # in a buffer all by itself.
['b4k-1', '--decode', {IN=>$a3k_nl[1]}, {OUT=>'a' x (3072+0)}], ['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-2', '--decode', {IN=>$a3k_nl[2]}, {OUT=>'a' x (3072+0)}],
['b4k-3', '--decode', {IN=>$a3k_nl[3]}, {OUT=>'a' x (3072+0)}], ['b4k-3', '--decode', {IN=>$a3k_nl[3]}, {OUT=>'a' x (3072+0)}],
);
if ($prog eq "base64")
{
push @Tests, (
['baddecode', '--decode', {IN=>'a'}, {OUT=>""}, ['baddecode', '--decode', {IN=>'a'}, {OUT=>""},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}], {ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}],
['baddecode2', '--decode', {IN=>'ab'}, {OUT=>"i"}, ['baddecode2', '--decode', {IN=>'ab'}, {OUT=>"i"},
@ -97,11 +115,12 @@ my @Tests =
['baddecode5', '--decode', {IN=>'Z==='}, {OUT=>""}, ['baddecode5', '--decode', {IN=>'Z==='}, {OUT=>""},
{ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}] {ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}]
); );
}
# For each non-failing test, create a --decode test using the # For each non-failing test, create a --decode test using the
# expected output as input. Also, add tests inserting newlines. # expected output as input. Also, add tests inserting newlines.
my @new; my @new;
foreach my $t (@Tests) foreach my $t (@Tests)
{ {
my $exit_val; my $exit_val;
my $in; my $in;
@ -144,11 +163,34 @@ foreach my $t (@Tests)
++$i; ++$i;
} }
} }
push @Tests, @new; push @Tests, @new;
}
my $save_temps = $ENV{DEBUG}; my $save_temps = $ENV{DEBUG};
my $verbose = $ENV{VERBOSE}; my $verbose = $ENV{VERBOSE};
my $prog = 'base64'; my $fail = 0;
my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); 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; exit $fail;

View File

@ -31,6 +31,7 @@ $@
{ {
my $fail = 0; my $fail = 0;
my @stdin_reading_commands = qw( my @stdin_reading_commands = qw(
base32
base64 base64
cat cat
cksum cksum