| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.152 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.3.152 |
| Problem: Xxd does not check for errors from library functions. |
| Solution: Add error checks. (Florian Zumbiehl) |
| Files: src/xxd/xxd.c |
| |
| |
| |
| |
| |
| *** 49,54 **** |
| --- 49,56 ---- |
| * 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,214 **** |
| |
| /* 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 xxdline __P((FILE *, char *, int)); |
| |
| #define TRY_SEEK /* attempt to use lseek, or skip forward by reading */ |
| --- 209,216 ---- |
| |
| /* Let's collect some prototypes */ |
| /* CodeWarrior is really picky about missing prototypes */ |
| ! 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,231 **** |
| #define HEX_CINCLUDE 2 |
| #define HEX_BITS 3 /* not hex a dump, but bits: 01111001 */ |
| |
| ! static void |
| ! exit_with_usage(pname) |
| ! char *pname; |
| { |
| 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); |
| --- 225,234 ---- |
| #define HEX_CINCLUDE 2 |
| #define HEX_BITS 3 /* not hex a dump, but bits: 01111001 */ |
| |
| ! 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,257 **** |
| --- 255,269 ---- |
| 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,270 **** |
| * |
| * 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; |
| { |
| int c, ign_garb = 1, n1 = -1, n2 = 0, n3, p = cols; |
| long have_off = 0, want_off = 0; |
| --- 271,281 ---- |
| * |
| * The name is historic and came from 'undo type opt h'. |
| */ |
| ! 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,324 **** |
| |
| if (base_off + want_off != have_off) |
| { |
| ! fflush(fpo); |
| #ifdef TRY_SEEK |
| c = fseek(fpo, base_off + want_off - have_off, 1); |
| if (c >= 0) |
| --- 329,336 ---- |
| |
| if (base_off + want_off != have_off) |
| { |
| ! if (fflush(fpo) != 0) |
| ! die(3); |
| #ifdef TRY_SEEK |
| c = fseek(fpo, base_off + want_off - have_off, 1); |
| if (c >= 0) |
| |
| *** 330,341 **** |
| return 5; |
| } |
| for (; have_off < base_off + want_off; have_off++) |
| ! putc(0, fpo); |
| } |
| |
| if (n2 >= 0 && n1 >= 0) |
| { |
| ! putc((n2 << 4) | n1, fpo); |
| have_off++; |
| want_off++; |
| n1 = -1; |
| --- 342,355 ---- |
| return 5; |
| } |
| for (; have_off < base_off + want_off; have_off++) |
| ! if (putc(0, fpo) == EOF) |
| ! die(3); |
| } |
| |
| if (n2 >= 0 && n1 >= 0) |
| { |
| ! if (putc((n2 << 4) | n1, fpo) == EOF) |
| ! die(3); |
| have_off++; |
| want_off++; |
| n1 = -1; |
| |
| *** 345,350 **** |
| --- 359,366 ---- |
| want_off = 0; |
| while ((c = getc(fpi)) != '\n' && c != EOF) |
| ; |
| + if (c == EOF && ferror(fpi)) |
| + die(2); |
| ign_garb = 1; |
| } |
| } |
| |
| *** 355,369 **** |
| want_off = 0; |
| while ((c = getc(fpi)) != '\n' && c != EOF) |
| ; |
| ign_garb = 1; |
| } |
| } |
| ! fflush(fpo); |
| #ifdef TRY_SEEK |
| fseek(fpo, 0L, 2); |
| #endif |
| ! fclose(fpo); |
| ! fclose(fpi); |
| return 0; |
| } |
| |
| --- 371,390 ---- |
| want_off = 0; |
| while ((c = getc(fpi)) != '\n' && c != EOF) |
| ; |
| + if (c == EOF && ferror(fpi)) |
| + die(2); |
| ign_garb = 1; |
| } |
| } |
| ! if (fflush(fpo) != 0) |
| ! die(3); |
| #ifdef TRY_SEEK |
| fseek(fpo, 0L, 2); |
| #endif |
| ! if (fclose(fpo) != 0) |
| ! die(3); |
| ! if (fclose(fpi) != 0) |
| ! die(2); |
| return 0; |
| } |
| |
| |
| *** 379,389 **** |
| * |
| * If nz is always positive, lines are never suppressed. |
| */ |
| ! static void |
| xxdline(fp, l, nz) |
| ! FILE *fp; |
| ! char *l; |
| ! int nz; |
| { |
| static char z[LLEN+1]; |
| static int zero_seen = 0; |
| --- 400,410 ---- |
| * |
| * If nz is always positive, lines are never suppressed. |
| */ |
| ! static void |
| xxdline(fp, l, nz) |
| ! FILE *fp; |
| ! char *l; |
| ! int nz; |
| { |
| static char z[LLEN+1]; |
| static int zero_seen = 0; |
| |
| *** 398,409 **** |
| if (nz < 0) |
| zero_seen--; |
| if (zero_seen == 2) |
| ! fputs(z, fp); |
| if (zero_seen > 2) |
| ! fputs("*\n", fp); |
| } |
| if (nz >= 0 || zero_seen > 0) |
| ! fputs(l, fp); |
| if (nz) |
| zero_seen = 0; |
| } |
| --- 419,433 ---- |
| if (nz < 0) |
| zero_seen--; |
| if (zero_seen == 2) |
| ! if (fputs(z, fp) == EOF) |
| ! die(3); |
| if (zero_seen > 2) |
| ! if (fputs("*\n", fp) == EOF) |
| ! die(3); |
| } |
| if (nz >= 0 || zero_seen > 0) |
| ! if (fputs(l, fp) == EOF) |
| ! die(3); |
| if (nz) |
| zero_seen = 0; |
| } |
| |
| *** 439,448 **** |
| 0070,0071,0372,0373,0374,0375,0376,0377 |
| }; |
| |
| ! int |
| main(argc, argv) |
| ! int argc; |
| ! char *argv[]; |
| { |
| FILE *fp, *fpo; |
| int c, e, p = 0, relseek = 1, negseek = 0, revert = 0; |
| --- 463,472 ---- |
| 0070,0071,0372,0373,0374,0375,0376,0377 |
| }; |
| |
| ! int |
| main(argc, argv) |
| ! int argc; |
| ! char *argv[]; |
| { |
| FILE *fp, *fpo; |
| int c, e, p = 0, relseek = 1, negseek = 0, revert = 0; |
| |
| *** 452,458 **** |
| int grplen; /* total chars per octet group */ |
| long length = -1, n = 0, seekoff = 0; |
| char l[LLEN+1]; |
| ! char *pname, *pp; |
| |
| #ifdef AMIGA |
| /* This program doesn't work when started from the Workbench */ |
| --- 476,482 ---- |
| int grplen; /* total chars per octet group */ |
| long length = -1, n = 0, seekoff = 0; |
| char l[LLEN+1]; |
| ! char *pp; |
| |
| #ifdef AMIGA |
| /* This program doesn't work when started from the Workbench */ |
| |
| *** 495,501 **** |
| else |
| { |
| if (!argv[2]) |
| ! exit_with_usage(pname); |
| cols = (int)strtol(argv[2], NULL, 0); |
| argv++; |
| argc--; |
| --- 519,525 ---- |
| else |
| { |
| if (!argv[2]) |
| ! exit_with_usage(); |
| cols = (int)strtol(argv[2], NULL, 0); |
| argv++; |
| argc--; |
| |
| *** 508,514 **** |
| else |
| { |
| if (!argv[2]) |
| ! exit_with_usage(pname); |
| octspergrp = (int)strtol(argv[2], NULL, 0); |
| argv++; |
| argc--; |
| --- 532,538 ---- |
| else |
| { |
| if (!argv[2]) |
| ! exit_with_usage(); |
| octspergrp = (int)strtol(argv[2], NULL, 0); |
| argv++; |
| argc--; |
| |
| *** 531,537 **** |
| else |
| { |
| if (!argv[2]) |
| ! exit_with_usage(pname); |
| #ifdef TRY_SEEK |
| if (argv[2][0] == '+') |
| relseek++; |
| --- 555,561 ---- |
| else |
| { |
| if (!argv[2]) |
| ! exit_with_usage(); |
| #ifdef TRY_SEEK |
| if (argv[2][0] == '+') |
| relseek++; |
| |
| *** 550,556 **** |
| else |
| { |
| if (!argv[2]) |
| ! exit_with_usage(pname); |
| length = strtol(argv[2], (char **)NULL, 0); |
| argv++; |
| argc--; |
| --- 574,580 ---- |
| else |
| { |
| if (!argv[2]) |
| ! exit_with_usage(); |
| length = strtol(argv[2], (char **)NULL, 0); |
| argv++; |
| argc--; |
| |
| *** 563,569 **** |
| break; |
| } |
| else if (pp[0] == '-' && pp[1]) /* unknown option */ |
| ! exit_with_usage(pname); |
| else |
| break; /* not an option */ |
| |
| --- 587,593 ---- |
| break; |
| } |
| else if (pp[0] == '-' && pp[1]) /* unknown option */ |
| ! exit_with_usage(); |
| else |
| break; /* not an option */ |
| |
| |
| *** 602,608 **** |
| octspergrp = cols; |
| |
| if (argc > 3) |
| ! exit_with_usage(pname); |
| |
| if (argc == 1 || (argv[1][0] == '-' && !argv[1][1])) |
| BIN_ASSIGN(fp = stdin, !revert); |
| --- 626,632 ---- |
| octspergrp = cols; |
| |
| if (argc > 3) |
| ! exit_with_usage(); |
| |
| if (argc == 1 || (argv[1][0] == '-' && !argv[1][1])) |
| BIN_ASSIGN(fp = stdin, !revert); |
| |
| *** 640,646 **** |
| fprintf(stderr, "%s: sorry, cannot revert this type of hexdump\n", pname); |
| return -1; |
| } |
| ! return huntype(fp, fpo, stderr, pname, cols, hextype, |
| negseek ? -seekoff : seekoff); |
| } |
| |
| --- 664,670 ---- |
| fprintf(stderr, "%s: sorry, cannot revert this type of hexdump\n", pname); |
| return -1; |
| } |
| ! return huntype(fp, fpo, stderr, cols, hextype, |
| negseek ? -seekoff : seekoff); |
| } |
| |
| |
| *** 664,670 **** |
| long s = seekoff; |
| |
| while (s--) |
| ! (void)getc(fp); |
| } |
| } |
| |
| --- 688,703 ---- |
| long s = seekoff; |
| |
| while (s--) |
| ! if (getc(fp) == EOF) |
| ! if (ferror(fp)) |
| ! { |
| ! die(2); |
| ! } |
| ! else |
| ! { |
| ! fprintf(stderr, "%s: sorry cannot seek.\n", pname); |
| ! return 4; |
| ! } |
| } |
| } |
| |
| |
| *** 672,725 **** |
| { |
| if (fp != stdin) |
| { |
| ! fprintf(fpo, "unsigned char %s", isdigit((int)argv[1][0]) ? "__" : ""); |
| for (e = 0; (c = argv[1][e]) != 0; e++) |
| ! putc(isalnum(c) ? c : '_', fpo); |
| ! fputs("[] = {\n", fpo); |
| } |
| |
| p = 0; |
| while ((length < 0 || p < length) && (c = getc(fp)) != EOF) |
| { |
| ! fprintf(fpo, (hexx == hexxa) ? "%s0x%02x" : "%s0X%02X", |
| ! (p % cols) ? ", " : ",\n "+2*!p, c); |
| p++; |
| } |
| |
| if (p) |
| ! fputs("\n};\n"+3*(fp == stdin), fpo); |
| |
| if (fp != stdin) |
| { |
| ! fprintf(fpo, "unsigned int %s", isdigit((int)argv[1][0]) ? "__" : ""); |
| for (e = 0; (c = argv[1][e]) != 0; e++) |
| ! putc(isalnum(c) ? c : '_', fpo); |
| ! fprintf(fpo, "_len = %d;\n", p); |
| } |
| |
| ! fclose(fp); |
| ! fclose(fpo); |
| return 0; |
| } |
| |
| if (hextype == HEX_POSTSCRIPT) |
| { |
| p = cols; |
| while ((length < 0 || n < length) && (e = getc(fp)) != EOF) |
| { |
| ! putchar(hexx[(e >> 4) & 0xf]); |
| ! putchar(hexx[(e ) & 0xf]); |
| n++; |
| if (!--p) |
| { |
| ! putchar('\n'); |
| p = cols; |
| } |
| } |
| if (p < cols) |
| ! putchar('\n'); |
| ! fclose(fp); |
| ! fclose(fpo); |
| return 0; |
| } |
| |
| --- 705,779 ---- |
| { |
| if (fp != stdin) |
| { |
| ! if (fprintf(fpo, "unsigned char %s", isdigit((int)argv[1][0]) ? "__" : "") < 0) |
| ! die(3); |
| for (e = 0; (c = argv[1][e]) != 0; e++) |
| ! 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) |
| { |
| ! 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) |
| ! if (fputs("\n};\n" + 3 * (fp == stdin), fpo) == EOF) |
| ! die(3); |
| |
| if (fp != stdin) |
| { |
| ! if (fprintf(fpo, "unsigned int %s", isdigit((int)argv[1][0]) ? "__" : "") < 0) |
| ! die(3); |
| for (e = 0; (c = argv[1][e]) != 0; e++) |
| ! if (putc(isalnum(c) ? c : '_', fpo) == EOF) |
| ! die(3); |
| ! if (fprintf(fpo, "_len = %d;\n", p) < 0) |
| ! die(3); |
| } |
| |
| ! 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) |
| { |
| ! if (putc(hexx[(e >> 4) & 0xf], fpo) == EOF |
| ! || putc(hexx[e & 0xf], fpo) == EOF) |
| ! die(3); |
| n++; |
| if (!--p) |
| { |
| ! if (putc('\n', fpo) == EOF) |
| ! die(3); |
| p = cols; |
| } |
| } |
| + if (e == EOF && ferror(fp)) |
| + die(2); |
| if (p < cols) |
| ! if (putc('\n', fpo) == EOF) |
| ! die(3); |
| ! if (fclose(fp)) |
| ! die(2); |
| ! if (fclose(fpo)) |
| ! die(3); |
| return 0; |
| } |
| |
| |
| *** 730,735 **** |
| --- 784,790 ---- |
| else /* hextype == HEX_BITS */ |
| grplen = 8 * octspergrp + 1; |
| |
| + e = 0; |
| while ((length < 0 || n < length) && (e = getc(fp)) != EOF) |
| { |
| if (p == 0) |
| |
| *** 771,776 **** |
| --- 826,833 ---- |
| p = 0; |
| } |
| } |
| + if (e == EOF && ferror(fp)) |
| + die(2); |
| if (p) |
| { |
| l[c = (11 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0'; |
| |
| *** 779,785 **** |
| else if (autoskip) |
| xxdline(fpo, l, -1); /* last chance to flush out suppressed lines */ |
| |
| ! fclose(fp); |
| ! fclose(fpo); |
| return 0; |
| } |
| --- 836,846 ---- |
| else if (autoskip) |
| xxdline(fpo, l, -1); /* last chance to flush out suppressed lines */ |
| |
| ! 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 : */ |
| |
| |
| |
| *** 716,717 **** |
| --- 716,719 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 152, |
| /**/ |
| |
| -- |
| Eye have a spelling checker, it came with my PC; |
| It plainly marks four my revue mistakes I cannot sea. |
| I've run this poem threw it, I'm sure your please to no, |
| It's letter perfect in it's weigh, my checker tolled me sew! |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ an exciting new programming language -- http://www.Zimbu.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |