diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | THANKS.in | 1 | ||||
-rw-r--r-- | bootstrap.conf | 1 | ||||
-rwxr-xr-x | build-aux/gen-lists-of-programs.sh | 1 | ||||
-rw-r--r-- | doc/coreutils.texi | 20 | ||||
-rw-r--r-- | man/.gitignore | 1 | ||||
-rw-r--r-- | man/base32.x | 4 | ||||
-rw-r--r-- | man/local.mk | 1 | ||||
-rwxr-xr-x | scripts/git-hooks/commit-msg | 2 | ||||
-rw-r--r-- | src/.gitignore | 1 | ||||
-rw-r--r-- | src/base64.c | 85 | ||||
-rw-r--r-- | src/local.mk | 5 | ||||
-rwxr-xr-x | tests/misc/base64.pl | 192 | ||||
-rwxr-xr-x | tests/misc/tty-eof.pl | 1 |
16 files changed, 216 insertions, 107 deletions
@@ -2,6 +2,7 @@ Here are the names of the programs in this package, each followed by the name(s) of its author(s). arch: David MacKenzie, Karel Zak +base32: Simon Josefsson base64: Simon Josefsson basename: David MacKenzie cat: Torbjörn Granlund, Richard M. Stallman @@ -7,6 +7,11 @@ GNU coreutils NEWS -*- outline -*- shred again uses defined patterns for all iteration counts. [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] @@ -7,7 +7,7 @@ arbitrary limits. 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 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 @@ -469,6 +469,7 @@ Nicolas François nicolas.francois@centraliens.net Niklas Edmundsson nikke@acc.umu.se Nikola Milutinovic Nikola.Milutinovic@ev.co.yu Nikolaus Rath Nikolaus@rath.org +Nikos Mavrogiannopoulos nmav@redhat.com Nima Nikzad nnikzad@ucla.edu Noah Friedman friedman@splode.com Noel Cragg noel@red-bean.com diff --git a/bootstrap.conf b/bootstrap.conf index 5c6d2bf8e..d0017f995 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -37,6 +37,7 @@ gnulib_modules=" linked-list backupfile base64 + base32 buffer-lcm c-strcase c-strtod diff --git a/build-aux/gen-lists-of-programs.sh b/build-aux/gen-lists-of-programs.sh index c95e59815..40c3a3236 100755 --- a/build-aux/gen-lists-of-programs.sh +++ b/build-aux/gen-lists-of-programs.sh @@ -42,6 +42,7 @@ build_if_possible_progs=' normal_progs=' [ base64 + base32 basename cat chcon diff --git a/doc/coreutils.texi b/doc/coreutils.texi index c35401f99..5589162e5 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -37,6 +37,7 @@ @dircategory Individual utilities @direntry * arch: (coreutils)arch invocation. Print machine hardware name. +* base32: (coreutils)base32 invocation. Base32 encode/decode data. * base64: (coreutils)base64 invocation. Base64 encode/decode data. * basename: (coreutils)basename invocation. Strip directory and suffix. * cat: (coreutils)cat invocation. Concatenate and write files. @@ -183,7 +184,7 @@ Free Documentation License''. @menu * Introduction:: Caveats, overview, and authors * 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 * Output of parts of files:: head tail split csplit * Summarizing files:: wc sum cksum md5sum sha1sum sha2 @@ -238,6 +239,7 @@ Output of entire files * tac invocation:: Concatenate and write files in reverse * nl invocation:: Number lines and write files * od invocation:: Write files in octal or other formats +* base32 invocation:: Transform data into printable data * base64 invocation:: Transform data into printable data Formatting file contents @@ -1551,6 +1553,7 @@ in some way. * tac invocation:: Concatenate and write files in reverse. * nl invocation:: Number lines and write files. * od invocation:: Write files in octal or other formats. +* base32 invocation:: Transform data into printable data. * base64 invocation:: Transform data into printable data. @end menu @@ -2138,6 +2141,20 @@ address. @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 @section @command{base64}: Transform data into printable data @@ -2155,6 +2172,7 @@ base64 --decode [@var{option}]@dots{} [@var{file}] @end smallexample 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 @uref{ftp://ftp.rfc-editor.org/in-notes/rfc4648.txt, RFC 4648}. diff --git a/man/.gitignore b/man/.gitignore index aef400292..37bc6c426 100644 --- a/man/.gitignore +++ b/man/.gitignore @@ -1,5 +1,6 @@ Makefile Makefile.in +base32.1 base64.1 basename.1 cat.1 diff --git a/man/base32.x b/man/base32.x new file mode 100644 index 000000000..f73de659d --- /dev/null +++ b/man/base32.x @@ -0,0 +1,4 @@ +[NAME] +base32 \- base32 encode/decode data and print to standard output +[DESCRIPTION] +.\" Add any additional description here diff --git a/man/local.mk b/man/local.mk index 45bda93e1..d1117606f 100644 --- a/man/local.mk +++ b/man/local.mk @@ -60,6 +60,7 @@ man/arch.1: src/uname$(EXEEXT) man/install.1: src/ginstall$(EXEEXT) man/test.1: src/[$(EXEEXT) +man/base32.1: src/base32$(EXEEXT) man/base64.1: src/base64$(EXEEXT) man/basename.1: src/basename$(EXEEXT) man/cat.1: src/cat$(EXEEXT) diff --git a/scripts/git-hooks/commit-msg b/scripts/git-hooks/commit-msg index 559a0ea8f..0e4dad6a8 100755 --- a/scripts/git-hooks/commit-msg +++ b/scripts/git-hooks/commit-msg @@ -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: # program names and a few general category names. 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 expr factor false fmt fold groups head hostid hostname id install join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp diff --git a/src/.gitignore b/src/.gitignore index e8bccbae5..c1f3b0d13 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -2,6 +2,7 @@ /.dirstamp \[ arch +base32 base64 basename cat diff --git a/src/base64.c b/src/base64.c index ec3fe0720..679044e40 100644 --- a/src/base64.c +++ b/src/base64.c @@ -32,12 +32,16 @@ #include "quotearg.h" #include "xfreopen.h" -#include "base64.h" +#define AUTHORS proper_name ("Simon Josefsson") -/* The official name of this program (e.g., no 'g' prefix). */ -#define PROGRAM_NAME "base64" +#if BASE_TYPE == 32 +# include "base32.h" +# define PROGRAM_NAME "base32" +#else +# include "base64.h" +# define PROGRAM_NAME "base64" +#endif -#define AUTHORS proper_name ("Simon Josefsson") static struct option const long_options[] = { @@ -59,8 +63,8 @@ usage (int status) { printf (_("\ Usage: %s [OPTION]... [FILE]\n\ -Base64 encode or decode FILE, or standard input, to standard output.\n\ -"), program_name); +Base%d encode or decode FILE, or standard input, to standard output.\n\ +"), program_name, BASE_TYPE); emit_stdin_note (); emit_mandatory_arg_note (); @@ -74,13 +78,13 @@ Base64 encode or decode FILE, or standard input, to standard output.\n\ "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); - fputs (_("\ + printf (_("\ \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\ -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"), - stdout); + PROGRAM_NAME, 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_B64BLOCKSIZE BASE64_LENGTH (ENC_BLOCKSIZE) + +#if BASE_TYPE == 32 +# define BASE_LENGTH BASE32_LENGTH +/* Note that increasing this may decrease performance if --ignore-garbage + is used, because of the memmove operation below. */ +# define DEC_BLOCKSIZE (1024*5) + +/* 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) -#define DEC_B64BLOCKSIZE BASE64_LENGTH (DEC_BLOCKSIZE) +# define DEC_BLOCKSIZE (1024*3) /* Ensure that BLOCKSIZE is a multiple of 3 and 4. */ -verify (ENC_BLOCKSIZE % 12 == 0); -verify (DEC_BLOCKSIZE % 12 == 0); +verify (ENC_BLOCKSIZE % 12 == 0); /* So padding chars only on last block. */ +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 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; char inbuf[ENC_BLOCKSIZE]; - char outbuf[ENC_B64BLOCKSIZE]; + char outbuf[BASE_LENGTH (ENC_BLOCKSIZE)]; size_t sum; do @@ -155,11 +182,11 @@ do_encode (FILE *in, FILE *out, uintmax_t wrap_column) if (sum > 0) { - /* Process input one block at a time. Note that ENC_BLOCKSIZE % - 3 == 0, so that no base64 pads will appear in output. */ - base64_encode (inbuf, sum, outbuf, BASE64_LENGTH (sum)); + /* Process input one block at a time. Note that ENC_BLOCKSIZE + is sized so that no pad chars will appear in output. */ + base_encode (inbuf, sum, outbuf, BASE_LENGTH (sum)); - wrap_write (outbuf, BASE64_LENGTH (sum), wrap_column, + wrap_write (outbuf, BASE_LENGTH (sum), wrap_column, ¤t_column, out); } } @@ -176,12 +203,12 @@ do_encode (FILE *in, FILE *out, uintmax_t wrap_column) static void do_decode (FILE *in, FILE *out, bool ignore_garbage) { - char inbuf[DEC_B64BLOCKSIZE]; + char inbuf[BASE_LENGTH (DEC_BLOCKSIZE)]; char outbuf[DEC_BLOCKSIZE]; size_t sum; - struct base64_decode_context ctx; + struct base_decode_context ctx; - base64_decode_ctx_init (&ctx); + base_decode_ctx_init (&ctx); do { @@ -192,13 +219,13 @@ do_decode (FILE *in, FILE *out, bool ignore_garbage) sum = 0; do { - n = fread (inbuf + sum, 1, DEC_B64BLOCKSIZE - sum, in); + n = fread (inbuf + sum, 1, BASE_LENGTH (DEC_BLOCKSIZE) - sum, in); if (ignore_garbage) { size_t i; for (i = 0; n > 0 && i < n;) - if (isbase64 (inbuf[sum + i]) || inbuf[sum + i] == '=') + if (isbase (inbuf[sum + i]) || inbuf[sum + i] == '=') i++; else 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)) 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. 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) break; 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) 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. */ 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; - /* 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; initialize_main (&argc, &argv); diff --git a/src/local.mk b/src/local.mk index 3fb167692..d0ceae4bd 100644 --- a/src/local.mk +++ b/src/local.mk @@ -94,6 +94,7 @@ LDADD = src/libver.a lib/libcoreutils.a $(LIBINTL) lib/libcoreutils.a # See [ below. src_arch_LDADD = $(LDADD) src_base64_LDADD = $(LDADD) +src_base32_LDADD = $(LDADD) src_basename_LDADD = $(LDADD) src_cat_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_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) # Ensure we don't link against libcoreutils.a as that lib is diff --git a/tests/misc/base64.pl b/tests/misc/base64.pl index fd75c624f..872535afb 100755 --- a/tests/misc/base64.pl +++ b/tests/misc/base64.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -# Exercise base64. +# Exercise base{32,64}. # Copyright (C) 2006-2015 Free Software Foundation, Inc. @@ -24,22 +24,27 @@ use strict; @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; # Return the encoding of a string of N 'a's. -sub enc($) +sub enc64($) { my ($n) = @_; my %remainder = ( 0 => '', 1 => 'YQ==', 2 => 'YWE=' ); return 'YWFh' x ($n / 3) . $remainder{$n % 3}; } -# Construct an encoded string of length 4KB, using 3K "a"s. -my $a3k = enc 3072; +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; -# 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. # Ensure that the result (if not the empty string) is newline-terminated. @@ -52,103 +57,140 @@ sub wrap($$) return $s; } -my @Tests = +my @Tests; + +sub gen_tests($) +{ + my ($prog) = @_; + @Tests= ( ['empty', {IN=>''}, {OUT=>""}], - ['inout', {IN=>'a'}, {OUT=>"YQ==\n"}], - ['wrap', '--wrap 0', {IN=>'foo'}, {OUT=>'Zm9v'}], - ['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}], - - ['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}], + ['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)}], + ['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}], + + ['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)}], + ['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)}], - - ['baddecode', '--decode', {IN=>'a'}, {OUT=>""}, - {ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}], - ['baddecode2', '--decode', {IN=>'ab'}, {OUT=>"i"}, - {ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}], - ['baddecode3', '--decode', {IN=>'Zzz'}, {OUT=>"g<"}, - {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}] ); -# 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) + if ($prog eq "base64") + { + push @Tests, ( + ['baddecode', '--decode', {IN=>'a'}, {OUT=>""}, + {ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}], + ['baddecode2', '--decode', {IN=>'ab'}, {OUT=>"i"}, + {ERR_SUBST => 's/.*: invalid input//'}, {ERR => "\n"}, {EXIT => 1}], + ['baddecode3', '--decode', {IN=>'Zzz'}, {OUT=>"g<"}, + {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}] + ); + } + + # 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; + 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' + # 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) + foreach my $e (@$t) { - ref $e && ref $e eq 'HASH' + ref $e && ref $e eq 'HASH' or next; - defined $e->{EXIT} + defined $e->{EXIT} and $exit_val = $e->{EXIT}; - defined $e->{IN} + defined $e->{IN} and $in = $e->{IN}; - if (defined $e->{OUT}) + if (defined $e->{OUT}) { - my $t = $e->{OUT}; - push @out, $t; - my $len = length $t; - foreach my $i (0..$len) + 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 + my $u = $t; + substr ($u, $i, 0) = "\n"; + push @out, $u; + 10 <= $i and last; } } } - $exit_val + $exit_val and next; - my $i = 0; - foreach my $o (@out) + my $i = 0; + foreach my $o (@out) { - push @new, ["d$i-$t->[0]", '--decode', {IN => $o}, {OUT => $in}]; - ++$i; + push @new, ["d$i-$t->[0]", '--decode', {IN => $o}, {OUT => $in}]; + ++$i; } } -push @Tests, @new; + push @Tests, @new; +} my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -my $prog = 'base64'; -my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $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; diff --git a/tests/misc/tty-eof.pl b/tests/misc/tty-eof.pl index c49efc24f..1bd912460 100755 --- a/tests/misc/tty-eof.pl +++ b/tests/misc/tty-eof.pl @@ -31,6 +31,7 @@ $@ { my $fail = 0; my @stdin_reading_commands = qw( + base32 base64 cat cksum |