# HG changeset patch # User Bram Moolenaar # Date 1301678080 -7200 # Node ID 0f7f66682a5563c76ab47e9976fd590d9423a013 # Parent b0d34143ebfc2290fdbf2f9608dabbc651c7a191 updated for version 7.3.152 Problem: Xxd does not check for errors from library functions. Solution: Add error checks. (Florian Zumbiehl) diff --git a/src/version.c b/src/version.c --- 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, diff --git a/src/xxd/xxd.c b/src/xxd/xxd.c --- 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 : */