coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] base32: A new program similar to base64


From: Pádraig Brady
Subject: [PATCH] base32: A new program similar to base64
Date: Tue, 1 Sep 2015 14:41:27 +0100

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.
* scripts/git-hooks/commit-msg: Add base32 to the template.
---
 AUTHORS                            |   1 +
 NEWS                               |   5 +
 README                             |   2 +-
 THANKS.in                          |   1 +
 bootstrap.conf                     |   1 +
 build-aux/gen-lists-of-programs.sh |   1 +
 doc/coreutils.texi                 |  20 +++-
 man/.gitignore                     |   1 +
 man/base32.x                       |   4 +
 man/local.mk                       |   1 +
 scripts/git-hooks/commit-msg       |   2 +-
 src/.gitignore                     |   1 +
 src/base64.c                       |  85 ++++++++++------
 src/local.mk                       |   5 +
 tests/misc/base64.pl               | 192 ++++++++++++++++++++++---------------
 15 files changed, 215 insertions(+), 107 deletions(-)
 create mode 100644 man/base32.x

diff --git a/AUTHORS b/AUTHORS
index 64c11d7..572ad59 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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
diff --git a/NEWS b/NEWS
index 54a0ab6..d247e9d 100644
--- a/NEWS
+++ b/NEWS
@@ -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]
 
diff --git a/README b/README
index 7473aeb..cb24e13 100644
--- a/README
+++ b/README
@@ -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
diff --git a/THANKS.in b/THANKS.in
index ba8e264..51c77ef 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -469,6 +469,7 @@ Nicolas Fran??ois                    address@hidden
 Niklas Edmundsson                   address@hidden
 Nikola Milutinovic                  address@hidden
 Nikolaus Rath                       address@hidden
+Nikos Mavrogiannopoulos             address@hidden
 Nima Nikzad                         address@hidden
 Noah Friedman                       address@hidden
 Noel Cragg                          address@hidden
diff --git a/bootstrap.conf b/bootstrap.conf
index 5c6d2bf..d0017f9 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 c95e598..40c3a32 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 c35401f..5589162 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 aef4002..37bc6c4 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 0000000..f73de65
--- /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 45bda93..d111760 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 559a0ea..0e4dad6 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 e8bccba..c1f3b0d 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 ec3fe07..8cc23e4 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 base%d 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 base%d alphabet.  Use --ignore-garbage to attempt to recover\n\
 from any other non-alphabet bytes in the encoded stream.\n"),
-             stdout);
+              BASE_TYPE, BASE_TYPE);
       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,
                       &current_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 3fb1676..d0ceae4 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 fd75c62..872535a 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;
-- 
2.4.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]