changeset 2752:0f7f66682a55 v7.3.152

updated for version 7.3.152 Problem: Xxd does not check for errors from library functions. Solution: Add error checks. (Florian Zumbiehl)
author Bram Moolenaar <bram@vim.org>
date Fri, 01 Apr 2011 19:14:40 +0200
parents b0d34143ebfc
children 6e042e124c4e
files src/version.c src/xxd/xxd.c
diffstat 2 files changed, 118 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/src/version.c
+++ b/src/version.c
@@ -715,6 +715,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    152,
+/**/
     151,
 /**/
     150,
--- a/src/xxd/xxd.c
+++ b/src/xxd/xxd.c
@@ -49,6 +49,8 @@
  *	    option -b added: 01000101 binary output in normal format.
  * 16.05.00 Added VAXC changes by Stephen P. Wall
  * 16.05.00 Improved MMS file and merge for VMS by Zoltan Arpadffy
+ * 2011 March  Better error handling by Florian Zumbiehl.
+ * 2011 April  Formatting by Bram Moolenaar
  *
  * (c) 1990-1998 by Juergen Weigert (jnweiger@informatik.uni-erlangen.de)
  *
@@ -207,8 +209,8 @@ char osver[] = "";
 
 /* Let's collect some prototypes */
 /* CodeWarrior is really picky about missing prototypes */
-static void exit_with_usage __P((char *));
-static int huntype __P((FILE *, FILE *, FILE *, char *, int, int, long));
+static void exit_with_usage __P((void));
+static int huntype __P((FILE *, FILE *, FILE *, int, int, long));
 static void xxdline __P((FILE *, char *, int));
 
 #define TRY_SEEK	/* attempt to use lseek, or skip forward by reading */
@@ -223,9 +225,10 @@ char hexxa[] = "0123456789abcdef01234567
 #define HEX_CINCLUDE 2
 #define HEX_BITS 3		/* not hex a dump, but bits: 01111001 */
 
-static void
-exit_with_usage(pname)
-char *pname;
+static char *pname;
+
+  static void
+exit_with_usage()
 {
   fprintf(stderr, "Usage:\n       %s [options] [infile [outfile]]\n", pname);
   fprintf(stderr, "    or\n       %s -r [-s [-]offset] [-c cols] [-ps] [infile [outfile]]\n", pname);
@@ -252,6 +255,15 @@ char *pname;
   exit(1);
 }
 
+  static void
+die(ret)
+  int ret;
+{
+  fprintf(stderr, "%s: ", pname);
+  perror(NULL);
+  exit(ret);
+}
+
 /*
  * Max. cols binary characters are decoded from the input stream per line.
  * Two adjacent garbage characters after evaluated data delimit valid data.
@@ -259,12 +271,11 @@ char *pname;
  *
  * The name is historic and came from 'undo type opt h'.
  */
-static int
-huntype(fpi, fpo, fperr, pname, cols, hextype, base_off)
-FILE *fpi, *fpo, *fperr;
-char *pname;
-int cols, hextype;
-long base_off;
+  static int
+huntype(fpi, fpo, fperr, cols, hextype, base_off)
+  FILE *fpi, *fpo, *fperr;
+  int cols, hextype;
+  long base_off;
 {
   int c, ign_garb = 1, n1 = -1, n2 = 0, n3, p = cols;
   long have_off = 0, want_off = 0;
@@ -318,7 +329,8 @@ long base_off;
 
       if (base_off + want_off != have_off)
 	{
-	  fflush(fpo);
+	  if (fflush(fpo) != 0)
+	    die(3);
 #ifdef TRY_SEEK
 	  c = fseek(fpo, base_off + want_off - have_off, 1);
 	  if (c >= 0)
@@ -330,12 +342,14 @@ long base_off;
 	      return 5;
 	    }
 	  for (; have_off < base_off + want_off; have_off++)
-	    putc(0, fpo);
+	    if (putc(0, fpo) == EOF)
+	      die(3);
 	}
 
       if (n2 >= 0 && n1 >= 0)
 	{
-	  putc((n2 << 4) | n1, fpo);
+	  if (putc((n2 << 4) | n1, fpo) == EOF)
+	    die(3);
 	  have_off++;
 	  want_off++;
 	  n1 = -1;
@@ -345,6 +359,8 @@ long base_off;
 	      want_off = 0;
 	      while ((c = getc(fpi)) != '\n' && c != EOF)
 		;
+	      if (c == EOF && ferror(fpi))
+		die(2);
 	      ign_garb = 1;
 	    }
 	}
@@ -355,15 +371,20 @@ long base_off;
 	    want_off = 0;
 	  while ((c = getc(fpi)) != '\n' && c != EOF)
 	    ;
+	  if (c == EOF && ferror(fpi))
+	    die(2);
 	  ign_garb = 1;
 	}
     }
-  fflush(fpo);
+  if (fflush(fpo) != 0)
+    die(3);
 #ifdef TRY_SEEK
   fseek(fpo, 0L, 2);
 #endif
-  fclose(fpo);
-  fclose(fpi);
+  if (fclose(fpo) != 0)
+    die(3);
+  if (fclose(fpi) != 0)
+    die(2);
   return 0;
 }
 
@@ -379,11 +400,11 @@ long base_off;
  *
  * If nz is always positive, lines are never suppressed.
  */
-static void
+  static void
 xxdline(fp, l, nz)
-FILE *fp;
-char *l;
-int nz;
+  FILE *fp;
+  char *l;
+  int nz;
 {
   static char z[LLEN+1];
   static int zero_seen = 0;
@@ -398,12 +419,15 @@ int nz;
 	  if (nz < 0)
 	    zero_seen--;
 	  if (zero_seen == 2)
-	    fputs(z, fp);
+	    if (fputs(z, fp) == EOF)
+	      die(3);
 	  if (zero_seen > 2)
-	    fputs("*\n", fp);
+	    if (fputs("*\n", fp) == EOF)
+	      die(3);
 	}
       if (nz >= 0 || zero_seen > 0)
-	fputs(l, fp);
+	if (fputs(l, fp) == EOF)
+	  die(3);
       if (nz)
 	zero_seen = 0;
     }
@@ -439,10 +463,10 @@ static unsigned char etoa64[] =
     0070,0071,0372,0373,0374,0375,0376,0377
 };
 
-int
+  int
 main(argc, argv)
-int argc;
-char *argv[];
+  int argc;
+  char *argv[];
 {
   FILE *fp, *fpo;
   int c, e, p = 0, relseek = 1, negseek = 0, revert = 0;
@@ -452,7 +476,7 @@ char *argv[];
   int grplen;		/* total chars per octet group */
   long length = -1, n = 0, seekoff = 0;
   char l[LLEN+1];
-  char *pname, *pp;
+  char *pp;
 
 #ifdef AMIGA
   /* This program doesn't work when started from the Workbench */
@@ -495,7 +519,7 @@ char *argv[];
 	  else
 	    {
 	      if (!argv[2])
-		exit_with_usage(pname);
+		exit_with_usage();
 	      cols = (int)strtol(argv[2], NULL, 0);
 	      argv++;
 	      argc--;
@@ -508,7 +532,7 @@ char *argv[];
 	  else
 	    {
 	      if (!argv[2])
-		exit_with_usage(pname);
+		exit_with_usage();
 	      octspergrp = (int)strtol(argv[2], NULL, 0);
 	      argv++;
 	      argc--;
@@ -531,7 +555,7 @@ char *argv[];
 	  else
 	    {
 	      if (!argv[2])
-		exit_with_usage(pname);
+		exit_with_usage();
 #ifdef TRY_SEEK
 	      if (argv[2][0] == '+')
 		relseek++;
@@ -550,7 +574,7 @@ char *argv[];
 	  else
 	    {
 	      if (!argv[2])
-		exit_with_usage(pname);
+		exit_with_usage();
 	      length = strtol(argv[2], (char **)NULL, 0);
 	      argv++;
 	      argc--;
@@ -563,7 +587,7 @@ char *argv[];
 	  break;
 	}
       else if (pp[0] == '-' && pp[1])	/* unknown option */
-	exit_with_usage(pname);
+	exit_with_usage();
       else
 	break;				/* not an option */
 
@@ -602,7 +626,7 @@ char *argv[];
     octspergrp = cols;
 
   if (argc > 3)
-    exit_with_usage(pname);
+    exit_with_usage();
 
   if (argc == 1 || (argv[1][0] == '-' && !argv[1][1]))
     BIN_ASSIGN(fp = stdin, !revert);
@@ -640,7 +664,7 @@ char *argv[];
 	  fprintf(stderr, "%s: sorry, cannot revert this type of hexdump\n", pname);
 	  return -1;
 	}
-      return huntype(fp, fpo, stderr, pname, cols, hextype,
+      return huntype(fp, fpo, stderr, cols, hextype,
 		negseek ? -seekoff : seekoff);
     }
 
@@ -664,7 +688,16 @@ char *argv[];
 	  long s = seekoff;
 
 	  while (s--)
-	    (void)getc(fp);
+	    if (getc(fp) == EOF)
+	      if (ferror(fp))
+		{
+		  die(2);
+		}
+	      else
+		{
+		  fprintf(stderr, "%s: sorry cannot seek.\n", pname);
+		  return 4;
+		}
 	}
     }
 
@@ -672,54 +705,75 @@ char *argv[];
     {
       if (fp != stdin)
 	{
-	  fprintf(fpo, "unsigned char %s", isdigit((int)argv[1][0]) ? "__" : "");
+	  if (fprintf(fpo, "unsigned char %s", isdigit((int)argv[1][0]) ? "__" : "") < 0)
+	    die(3);
 	  for (e = 0; (c = argv[1][e]) != 0; e++)
-	    putc(isalnum(c) ? c : '_', fpo);
-	  fputs("[] = {\n", fpo);
+	    if (putc(isalnum(c) ? c : '_', fpo) == EOF)
+	      die(3);
+	  if (fputs("[] = {\n", fpo) == EOF)
+	    die(3);
 	}
 
       p = 0;
+      c = 0;
       while ((length < 0 || p < length) && (c = getc(fp)) != EOF)
 	{
-	  fprintf(fpo, (hexx == hexxa) ? "%s0x%02x" : "%s0X%02X",
-	    (p % cols) ? ", " : ",\n  "+2*!p,  c);
+	  if (fprintf(fpo, (hexx == hexxa) ? "%s0x%02x" : "%s0X%02X",
+		(p % cols) ? ", " : ",\n  "+2*!p,  c) < 0)
+	    die(3);
 	  p++;
 	}
+      if (c == EOF && ferror(fp))
+	die(2);
 
       if (p)
-	fputs("\n};\n"+3*(fp == stdin), fpo);
+	if (fputs("\n};\n" + 3 * (fp == stdin), fpo) == EOF)
+	  die(3);
 
       if (fp != stdin)
 	{
-	  fprintf(fpo, "unsigned int %s", isdigit((int)argv[1][0]) ? "__" : "");
+	  if (fprintf(fpo, "unsigned int %s", isdigit((int)argv[1][0]) ? "__" : "") < 0)
+	    die(3);
 	  for (e = 0; (c = argv[1][e]) != 0; e++)
-	    putc(isalnum(c) ? c : '_', fpo);
-	  fprintf(fpo, "_len = %d;\n", p);
+	    if (putc(isalnum(c) ? c : '_', fpo) == EOF)
+	      die(3);
+	  if (fprintf(fpo, "_len = %d;\n", p) < 0)
+	    die(3);
 	}
 
-      fclose(fp);
-      fclose(fpo);
+      if (fclose(fp))
+	die(2);
+      if (fclose(fpo))
+	die(3);
       return 0;
     }
 
   if (hextype == HEX_POSTSCRIPT)
     {
       p = cols;
+      e = 0;
       while ((length < 0 || n < length) && (e = getc(fp)) != EOF)
 	{
-	  putchar(hexx[(e >> 4) & 0xf]);
-	  putchar(hexx[(e     ) & 0xf]);
+	  if (putc(hexx[(e >> 4) & 0xf], fpo) == EOF
+		  || putc(hexx[e & 0xf], fpo) == EOF)
+	    die(3);
 	  n++;
 	  if (!--p)
 	    {
-	      putchar('\n');
+	      if (putc('\n', fpo) == EOF)
+		die(3);
 	      p = cols;
 	    }
 	}
+      if (e == EOF && ferror(fp))
+	die(2);
       if (p < cols)
-	putchar('\n');
-      fclose(fp);
-      fclose(fpo);
+	if (putc('\n', fpo) == EOF)
+	  die(3);
+      if (fclose(fp))
+	die(2);
+      if (fclose(fpo))
+	die(3);
       return 0;
     }
 
@@ -730,6 +784,7 @@ char *argv[];
   else	/* hextype == HEX_BITS */
     grplen = 8 * octspergrp + 1;
 
+  e = 0;
   while ((length < 0 || n < length) && (e = getc(fp)) != EOF)
     {
       if (p == 0)
@@ -771,6 +826,8 @@ char *argv[];
 	  p = 0;
 	}
     }
+  if (e == EOF && ferror(fp))
+    die(2);
   if (p)
     {
       l[c = (11 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
@@ -779,7 +836,11 @@ char *argv[];
   else if (autoskip)
     xxdline(fpo, l, -1);	/* last chance to flush out suppressed lines */
 
-  fclose(fp);
-  fclose(fpo);
+  if (fclose(fp))
+    die(2);
+  if (fclose(fpo))
+    die(3);
   return 0;
 }
+
+/* vi:set ts=8 sw=4 sts=2 cino+={2 cino+=n-2 : */