git: 5cb28f797977 - main - bintrans: Error out if writing to the output failed.

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Thu, 01 Feb 2024 13:11:09 UTC
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=5cb28f7979773715615cc2131fe40e0c5879ed1d

commit 5cb28f7979773715615cc2131fe40e0c5879ed1d
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2024-02-01 13:10:31 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2024-02-01 13:10:31 +0000

    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 | 33 ++++++++++++++++++++++-----------
 usr.bin/bintrans/uuencode.c |  4 ++--
 2 files changed, 24 insertions(+), 13 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,11 +331,22 @@ checkend(const char *ptr, const char *end, const char *msg)
 		warnx("%s: %s: %s", infile, outfile, msg);
 		return (1);
 	}
-	if (fclose(outfp) != 0) {
+	return (0);
+}
+
+static int
+checkout(int rval)
+{
+	if (fflush(outfp) != 0) {
 		warn("%s: %s", infile, outfile);
-		return (1);
+		rval = 1;
 	}
-	return (0);
+	if (outfp != stdout) {
+		(void)fclose(outfp);
+		outfp = stdout;
+	}
+	outfile = "/dev/stdout";
+	return (rval);
 }
 
 static int
@@ -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);
 }