Module Name:    src
Committed By:   christos
Date:           Sun Feb 28 23:12:23 UTC 2016

Modified Files:
        src/bin/sh: output.c parser.c show.c

Log Message:
Bug fixes to handling of unterminated here documents
(they should be, and now are, a syntax error), and
miscellaneous other minor cleanups. (from kre)


To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/bin/sh/output.c
cvs rdiff -u -r1.101 -r1.102 src/bin/sh/parser.c
cvs rdiff -u -r1.30 -r1.31 src/bin/sh/show.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/bin/sh/output.c
diff -u src/bin/sh/output.c:1.33 src/bin/sh/output.c:1.34
--- src/bin/sh/output.c:1.33	Mon Aug 30 02:27:14 2010
+++ src/bin/sh/output.c	Sun Feb 28 18:12:23 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: output.c,v 1.33 2010/08/30 06:27:14 christos Exp $	*/
+/*	$NetBSD: output.c,v 1.34 2016/02/28 23:12:23 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)output.c	8.2 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: output.c,v 1.33 2010/08/30 06:27:14 christos Exp $");
+__RCSID("$NetBSD: output.c,v 1.34 2016/02/28 23:12:23 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -524,7 +524,7 @@ xwrite(int fd, char *buf, int nbytes)
 
 	n = nbytes;
 	ntry = 0;
-	for (;;) {
+	while (n > 0) {
 		i = write(fd, buf, n);
 		if (i > 0) {
 			if ((n -= i) <= 0)
@@ -538,6 +538,7 @@ xwrite(int fd, char *buf, int nbytes)
 			return -1;
 		}
 	}
+	return nbytes;
 }
 
 

Index: src/bin/sh/parser.c
diff -u src/bin/sh/parser.c:1.101 src/bin/sh/parser.c:1.102
--- src/bin/sh/parser.c:1.101	Sat Feb 27 11:28:50 2016
+++ src/bin/sh/parser.c	Sun Feb 28 18:12:23 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: parser.c,v 1.101 2016/02/27 16:28:50 christos Exp $	*/
+/*	$NetBSD: parser.c,v 1.102 2016/02/28 23:12:23 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)parser.c	8.7 (Berkeley) 5/16/95";
 #else
-__RCSID("$NetBSD: parser.c,v 1.101 2016/02/27 16:28:50 christos Exp $");
+__RCSID("$NetBSD: parser.c,v 1.102 2016/02/28 23:12:23 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -122,6 +122,8 @@ STATIC void synerror(const char *) __dea
 STATIC void setprompt(int);
 
 
+static const char EOFhere[] = "EOF reading here (<<) document";
+
 /*
  * Read and parse a command.  Returns NEOF on end of file.  (NULL is a
  * valid parse tree indicating a blank line.)
@@ -720,14 +722,17 @@ parseheredoc(void)
 
 	while (heredoclist) {
 		int c;
+
 		here = heredoclist;
 		heredoclist = here->next;
 		if (needprompt) {
 			setprompt(2);
 			needprompt = 0;
 		}
-		if ((c = pgetc()) == PEOF)
-			continue;
+		if ((c = pgetc()) == PEOF) {
+			synerror(EOFhere);
+			/* NOTREACHED */
+		}
 		readtoken1(c, here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
 		    here->eofmark, here->striptabs);
 		n = stalloc(sizeof(struct narg));
@@ -913,7 +918,7 @@ breakloop:
 
 /*
  * We used to remember only the current syntax, variable nesting level,
- * double quote state for each var nexting level, and arith nesting
+ * double quote state for each var nesting level, and arith nesting
  * level (unrelated to var nesting) and one prev syntax when in arith
  * syntax.  This worked for simple cases, but can't handle arith inside
  * var expansion inside arith inside var with some quoted and some not.
@@ -924,7 +929,7 @@ breakloop:
  * Every time something changes, which will eventually end and should
  * revert to the previous state, we push this stack, and then pop it
  * again later (that is every ${} with an operator (to parse the word
- * or pattern that follows) ${x} and $x are too * simple to need it)
+ * or pattern that follows) ${x} and $x are too simple to need it)
  * $(( )) $( ) and "...".   Always.   Really, always!
  *
  * The stack is implemented as one static (on the C stack) base block
@@ -1321,6 +1326,8 @@ endword:
 
 checkend: {
 	if (eofmark) {
+		if (c == PEOF)
+			synerror(EOFhere);
 		if (striptabs) {
 			while (c == '\t')
 				c = pgetc();
@@ -1339,7 +1346,8 @@ checkend: {
 				} else {
 					pushstring(line, strlen(line), NULL);
 				}
-			}
+			} else
+				synerror(EOFhere);
 		}
 	}
 	goto checkend_return;

Index: src/bin/sh/show.c
diff -u src/bin/sh/show.c:1.30 src/bin/sh/show.c:1.31
--- src/bin/sh/show.c:1.30	Sat Feb 27 18:50:13 2016
+++ src/bin/sh/show.c	Sun Feb 28 18:12:23 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: show.c,v 1.30 2016/02/27 23:50:13 christos Exp $	*/
+/*	$NetBSD: show.c,v 1.31 2016/02/28 23:12:23 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)show.c	8.3 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: show.c,v 1.30 2016/02/27 23:50:13 christos Exp $");
+__RCSID("$NetBSD: show.c,v 1.31 2016/02/28 23:12:23 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -122,7 +122,7 @@ binop:
 		break;
 	case NCMD:
 		len += shcmd(n, fp);
-		if (nl)
+		if (nl && len > 0)
 			len = 0, putc('\n', fp);
 		break;
 	case NPIPE:
@@ -185,6 +185,8 @@ shcmd(union node *cmd, FILE *fp)
 			case NFROM:	s = "<";  dftfd = 0; len += 1; break;
 			case NFROMFD:	s = "<&"; dftfd = 0; len += 2; break;
 			case NFROMTO:	s = "<>"; dftfd = 0; len += 2; break;
+			case NXHERE:	/* FALLTHROUGH */ 
+			case NHERE:	s = "<<"; dftfd = 0; len += 2; break;
 			default:   s = "*error*"; dftfd = 0; len += 7; break;
 		}
 		if (np->nfile.fd != dftfd)
@@ -192,6 +194,14 @@ shcmd(union node *cmd, FILE *fp)
 		fputs(s, fp);
 		if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
 			len += fprintf(fp, "%d", np->ndup.dupfd);
+		} else
+		    if (np->nfile.type == NHERE || np->nfile.type == NXHERE) {
+			if (np->nfile.type == NHERE)
+				fputc('\\', fp);
+			fputs("!!!\n", fp);
+			fputs(np->nhere.doc->narg.text, fp);
+			fputs("!!!", fp);
+			len = 3;
 		} else {
 			len += sharg(np->nfile.fname, fp);
 		}

Reply via email to