[PATCH 2/2] Be more careful in guarding against pathological "begin" lines

Filipe Brandenburger <[email protected]> Fri, 22 May 2015 08:50:05 -0700
Newsgroups gmane.comp.gnu.utils.bugs
Message-ID <[email protected]>
From: Bruce Korb <[email protected]>

---
 ChangeLog      |  5 +++++
 src/uudecode.c | 29 ++++++++++++++++++++---------
 2 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 13bf58b448f0..8434437572a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-05-21  Bruce Korb  <[email protected]>
+
+	* src/uudecode.c (decode): be more careful in guarding against
+	pathological "begin" lines
+
 2015-05-20  Filipe Brandenburger  <[email protected]>
 	Bruce Korb  <[email protected]>
 	Paul Eggert  <[email protected]>
diff --git a/src/uudecode.c b/src/uudecode.c
index fa214d3d3a13..0621c9992de4 100644
--- a/src/uudecode.c
+++ b/src/uudecode.c
@@ -63,6 +63,9 @@ static char const cright_years_z[] =
 #ifndef _
 # define _(str) (str)
 #endif
+#ifndef NL
+#define NL '\n'
+#endif
 
 /*=====================================================================\
 | uudecode [FILE ...]						       |
@@ -157,11 +160,11 @@ read_stduu (char const * inname, char const * outname)
     if (buf[0] != 'e') break;
     if (buf[1] != 'n') break;
     if (buf[2] != 'd') break;
-    if (buf[3] == '\n')
+    if (buf[3] == NL)
       return UUDECODE_EXIT_SUCCESS;
 
     if (buf[3] != '\r') break;
-    if (buf[4] == '\n')
+    if (buf[4] == NL)
       return UUDECODE_EXIT_SUCCESS;
   } while (0);
 
@@ -384,14 +387,25 @@ decode (char const * inname)
                _("%s: Invalid or missing 'begin' line\n"), inname);
 	}
 
+      if (strchr (buf, NL) == NULL)
+        goto bad_beginning;
+
       if (strncmp (buf, "begin", 5) == 0)
 	{
           char * scan = buf+5;
-          if (*scan == '-')
+
+        check_begin_option:
+
+          switch (*scan) {
+          default:
+            goto bad_beginning;
+          case ' ':
+            break;
+          case '-':
             {
               static char const base64[]  = "ase64";
               static char const encoded[] = "encoded";
-            check_begin_option:
+
               if (*++scan == 'b')
                 {
                   if (strncmp (scan+1, base64, sizeof (base64) - 1) != 0)
@@ -411,12 +425,9 @@ decode (char const * inname)
                   scan += sizeof (encoded) - 1; /* 'e' is included */
                 }
 
-              switch (*scan) {
-              case ' ': break; /* no more begin options */
-              case '-': goto check_begin_option;
-              default:  goto bad_beginning;
-              }
+              goto check_begin_option;
 	    }
+          }
 
 	  if (sscanf (scan, " %o %[^\n]", &mode, buf) == 2)
 	    break;
-- 
2.2.0.rc0.207.ga3a616c