From 5cb28f7979773715615cc2131fe40e0c5879ed1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 1 Feb 2024 14:10:31 +0100 Subject: [PATCH] bintrans: Error out if writing to the output failed. - Cover all code paths. - When decoding, check all output files, not just the last one. - A simple `ferror()` check is not enough as an error may later occur while flushing whatever remains in the output buffer. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: allanjude Differential Revision: https://reviews.freebsd.org/D43532 --- usr.bin/bintrans/uudecode.c | 35 +++++++++++++++++++++++------------ usr.bin/bintrans/uuencode.c | 4 ++-- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/usr.bin/bintrans/uudecode.c b/usr.bin/bintrans/uudecode.c index 56128d230b00..5a252b71055e 100644 --- a/usr.bin/bintrans/uudecode.c +++ b/usr.bin/bintrans/uudecode.c @@ -331,13 +331,24 @@ checkend(const char *ptr, const char *end, const char *msg) warnx("%s: %s: %s", infile, outfile, msg); return (1); } - if (fclose(outfp) != 0) { - warn("%s: %s", infile, outfile); - return (1); - } return (0); } +static int +checkout(int rval) +{ + if (fflush(outfp) != 0) { + warn("%s: %s", infile, outfile); + rval = 1; + } + if (outfp != stdout) { + (void)fclose(outfp); + outfp = stdout; + } + outfile = "/dev/stdout"; + return (rval); +} + static int uu_decode(void) { @@ -349,9 +360,9 @@ uu_decode(void) for (;;) { switch (get_line(buf, sizeof(buf))) { case 0: - return (0); + return (checkout(0)); case 1: - return (1); + return (checkout(1)); } #define DEC(c) (((c) - ' ') & 077) /* single character decode */ @@ -408,11 +419,11 @@ uu_decode(void) } switch (get_line(buf, sizeof(buf))) { case 0: - return (0); + return (checkout(0)); case 1: - return (1); + return (checkout(1)); default: - return (checkend(buf, "end", "no \"end\" line")); + return (checkout(checkend(buf, "end", "no \"end\" line"))); } } @@ -430,9 +441,9 @@ base64_decode(void) switch (get_line(inbuf + strlen(inbuf), sizeof(inbuf) - strlen(inbuf))) { case 0: - return (0); + return (checkout(0)); case 1: - return (1); + return (checkout(1)); } count = 0; @@ -459,7 +470,7 @@ base64_decode(void) break; fwrite(outbuf, 1, n, outfp); } - return (checkend(inbuf, "====", "error decoding base64 input stream")); + return (checkout(checkend(inbuf, "====", "error decoding base64 input stream"))); } static void diff --git a/usr.bin/bintrans/uuencode.c b/usr.bin/bintrans/uuencode.c index 221811c56d4d..db0419ef0dac 100644 --- a/usr.bin/bintrans/uuencode.c +++ b/usr.bin/bintrans/uuencode.c @@ -74,7 +74,7 @@ main_base64_encode(const char *in, const char *w) if (w != NULL) columns = arg_to_col(w); base64_encode(); - if (ferror(output)) + if (fflush(output) != 0) errx(1, "write error"); exit(0); } @@ -144,7 +144,7 @@ main_encode(int argc, char *argv[]) base64_encode(); else encode(); - if (ferror(output)) + if (fflush(output) != 0) errx(1, "write error"); exit(0); }