Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: Plug some fd leaks in bin_print



Found by Coverity (Issue 439120).
---
 Src/builtin.c | 60 ++++++++++++++++++++++++-----------------------------------
 1 file changed, 24 insertions(+), 36 deletions(-)

diff --git a/Src/builtin.c b/Src/builtin.c
index 13c9a96..4a780bb 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -3783,7 +3783,7 @@ bin_print(char *name, char **args, Options ops, int func)
     /* compute lengths, and interpret according to -P, -D, -e, etc. */
     argc = arrlen(args);
     len = (int *) hcalloc(argc * sizeof(int));
-    for(n = 0; n < argc; n++) {
+    for (n = 0; n < argc; n++) {
 	/* first \ sequences */
 	if (fmt ||
 	    (!OPT_ISSET(ops,'e') &&
@@ -3850,7 +3850,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	    char *argptr = OPT_ARG(ops,'u'), *eptr;
 	    /* Handle undocumented feature that -up worked */
 	    if (!strcmp(argptr, "p")) {
-		fdarg= coprocout;
+		fdarg = coprocout;
 		if (fdarg < 0) {
 		    zwarnnam(name, "-p: no coprocess");
 		    return 1;
@@ -3967,12 +3967,14 @@ bin_print(char *name, char **args, Options ops, int func)
 	    char *eptr, *argptr = OPT_ARG(ops,'C');
 	    nc = (int)zstrtol(argptr, &eptr, 10);
 	    if (*eptr) {
-		zwarnnam(name, "number expcted after -%c: %s", 'C', argptr);
-		return 1;
+		zwarnnam(name, "number expected after -%c: %s", 'C', argptr);
+		ret = 1;
+		goto out_print;
 	    }
 	    if (nc <= 0) {
 		zwarnnam(name, "invalid number of columns: %s", argptr);
-		return 1;
+		ret = 1;
+		goto out_print;
 	    }
 	    /*
 	     * n: number of elements
@@ -4052,13 +4054,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	    }
 	    fputc(OPT_ISSET(ops,'N') ? '\0' : '\n', fout);
 	}
-	/* Testing EBADF special-cases >&- redirections */
-	if ((fout != stdout) ? (fclose(fout) != 0) :
-	    (fflush(fout) != 0 && errno != EBADF)) {
-            zwarnnam(name, "write error: %e", errno);
-            ret = 1;
-	}
-	return ret;
+	goto out_print;
     }
 
     /* normal output */
@@ -4076,7 +4072,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	    queue_signals();
 	    zpushnode(bufstack, sepjoin(args, NULL, 0));
 	    unqueue_signals();
-	    return 0;
+	    goto out_print;
 	}
 	/* -s option -- add the arguments to the history list */
 	if (OPT_ISSET(ops,'s') || OPT_ISSET(ops,'S')) {
@@ -4092,7 +4088,8 @@ bin_print(char *name, char **args, Options ops, int func)
 		    short *words;
 		    if (nwords > 1) {
 			zwarnnam(name, "option -S takes a single argument");
-			return 1;
+			ret = 1;
+			goto out_print;
 		    }
 		    words = NULL;
 		    wordsize = 0;
@@ -4134,13 +4131,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	}
 	if (!(OPT_ISSET(ops,'n') || nnl))
 	    fputc(OPT_ISSET(ops,'N') ? '\0' : '\n', fout);
-	/* Testing EBADF special-cases >&- redirections */
-	if ((fout != stdout) ? (fclose(fout) != 0) :
-	    (fflush(fout) != 0 && errno != EBADF)) {
-            zwarnnam(name, "write error: %e", errno);
-            ret = 1;
-	}
-	return ret;
+	goto out_print;
     }
 
     /*
@@ -4150,6 +4141,9 @@ bin_print(char *name, char **args, Options ops, int func)
      */
 
     if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s')) {
+	if (fout != stdout)
+	    fclose(fout);
+	fout = stdout;
 #ifdef HAVE_OPEN_MEMSTREAM
     	if ((fout = open_memstream(&buf, &mcount)) == NULL)
 	    zwarnnam(name, "open_memstream failed");
@@ -4200,9 +4194,8 @@ bin_print(char *name, char **args, Options ops, int func)
 		    if (narg > argc) {
 		    	zwarnnam(name, "%d: argument specifier out of range",
 				 narg);
-			if (fout != stdout)
-			    fclose(fout);
-			return 1;
+			ret = 1;
+			goto out_print;
 		    } else {
 		    	if (narg > maxarg) maxarg = narg;
 		    	curarg = *(first + narg - 1);
@@ -4233,9 +4226,8 @@ bin_print(char *name, char **args, Options ops, int func)
 		    	    zwarnnam(name,
 				     "%d: argument specifier out of range",
 				     narg);
-			    if (fout != stdout)
-				fclose(fout);
-			    return 1;
+			    ret = 1;
+			    goto out_print;
 			} else {
 		    	    if (narg > maxarg) maxarg = narg;
 		    	    argp = first + narg - 1;
@@ -4262,9 +4254,8 @@ bin_print(char *name, char **args, Options ops, int func)
 		    		zwarnnam(name,
 					 "%d: argument specifier out of range",
 					 narg);
-				if (fout != stdout)
-				    fclose(fout);
-				return 1;
+				ret = 1;
+				goto out_print;
 			    } else {
 		    		if (narg > maxarg) maxarg = narg;
 		    		argp = first + narg - 1;
@@ -4414,12 +4405,8 @@ bin_print(char *name, char **args, Options ops, int func)
 		}
 		zwarnnam(name, "%s: invalid directive", start);
 		if (*c) c[1] = save;
-		/* Testing EBADF special-cases >&- redirections */
-		if ((fout != stdout) ? (fclose(fout) != 0) :
-		    (fflush(fout) != 0 && errno != EBADF)) {
-		    zwarnnam(name, "write error: %e", errno);
-		}
-		return 1;
+		ret = 1;
+		goto out_print;
 	    }
 
 	    if (type > 0) {
@@ -4536,6 +4523,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	unqueue_signals();
     }
 
+out_print:
     /* Testing EBADF special-cases >&- redirections */
     if ((fout != stdout) ? (fclose(fout) != 0) :
 	(fflush(fout) != 0 && errno != EBADF)) {
-- 
2.2.0.GIT



Messages sorted by: Reverse Date, Date, Thread, Author