Wed Nov 5 22:04:43 2008 UTC ()
PR/11317: Hubert Feyrer: Recognize mismatched parentheses inside old style
command substitution.


(christos)
diff -r1.69 -r1.70 src/bin/sh/parser.c

cvs diff -r1.69 -r1.70 src/bin/sh/parser.c (expand / switch to unified diff)

--- src/bin/sh/parser.c 2008/08/23 10:05:52 1.69
+++ src/bin/sh/parser.c 2008/11/05 22:04:43 1.70
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: parser.c,v 1.69 2008/08/23 10:05:52 christos Exp $ */ 1/* $NetBSD: parser.c,v 1.70 2008/11/05 22:04:43 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1991, 1993 4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Kenneth Almquist. 8 * Kenneth Almquist.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36#ifndef lint 36#ifndef lint
37#if 0 37#if 0
38static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; 38static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95";
39#else 39#else
40__RCSID("$NetBSD: parser.c,v 1.69 2008/08/23 10:05:52 christos Exp $"); 40__RCSID("$NetBSD: parser.c,v 1.70 2008/11/05 22:04:43 christos Exp $");
41#endif 41#endif
42#endif /* not lint */ 42#endif /* not lint */
43 43
44#include <stdlib.h> 44#include <stdlib.h>
45 45
46#include "shell.h" 46#include "shell.h"
47#include "parser.h" 47#include "parser.h"
48#include "nodes.h" 48#include "nodes.h"
49#include "expand.h" /* defines rmescapes() */ 49#include "expand.h" /* defines rmescapes() */
50#include "eval.h" /* defines commandname */ 50#include "eval.h" /* defines commandname */
51#include "redir.h" /* defines copyfd() */ 51#include "redir.h" /* defines copyfd() */
52#include "syntax.h" 52#include "syntax.h"
53#include "options.h" 53#include "options.h"
@@ -1384,26 +1384,27 @@ parsebackq: { @@ -1384,26 +1384,27 @@ parsebackq: {
1384 str = ckmalloc(savelen); 1384 str = ckmalloc(savelen);
1385 memcpy(str, stackblock(), savelen); 1385 memcpy(str, stackblock(), savelen);
1386 } 1386 }
1387 savehandler = handler; 1387 savehandler = handler;
1388 handler = &jmploc; 1388 handler = &jmploc;
1389 INTON; 1389 INTON;
1390 if (oldstyle) { 1390 if (oldstyle) {
1391 /* We must read until the closing backquote, giving special 1391 /* We must read until the closing backquote, giving special
1392 treatment to some slashes, and then push the string and 1392 treatment to some slashes, and then push the string and
1393 reread it as input, interpreting it normally. */ 1393 reread it as input, interpreting it normally. */
1394 char *pout; 1394 char *pout;
1395 int pc; 1395 int pc;
1396 int psavelen; 1396 int psavelen;
 1397 int nparen = 0;
1397 char *pstr; 1398 char *pstr;
1398 1399
1399 1400
1400 STARTSTACKSTR(pout); 1401 STARTSTACKSTR(pout);
1401 for (;;) { 1402 for (;;) {
1402 if (needprompt) { 1403 if (needprompt) {
1403 setprompt(2); 1404 setprompt(2);
1404 needprompt = 0; 1405 needprompt = 0;
1405 } 1406 }
1406 switch (pc = pgetc()) { 1407 switch (pc = pgetc()) {
1407 case '`': 1408 case '`':
1408 goto done; 1409 goto done;
1409 1410
@@ -1416,43 +1417,53 @@ parsebackq: { @@ -1416,43 +1417,53 @@ parsebackq: {
1416 setprompt(0); 1417 setprompt(0);
1417 /* 1418 /*
1418 * If eating a newline, avoid putting 1419 * If eating a newline, avoid putting
1419 * the newline into the new character 1420 * the newline into the new character
1420 * stream (via the STPUTC after the 1421 * stream (via the STPUTC after the
1421 * switch). 1422 * switch).
1422 */ 1423 */
1423 continue; 1424 continue;
1424 } 1425 }
1425 if (pc != '\\' && pc != '`' && pc != '$' 1426 if (pc != '\\' && pc != '`' && pc != '$'
1426 && (!ISDBLQUOTE() || pc != '"')) 1427 && (!ISDBLQUOTE() || pc != '"'))
1427 STPUTC('\\', pout); 1428 STPUTC('\\', pout);
1428 break; 1429 break;
 1430 case '(':
 1431 nparen++;
 1432 break;
 1433
 1434 case ')':
 1435 if (--nparen < 0)
 1436 synerror("`)' unexpected");
 1437 break;
1429 1438
1430 case '\n': 1439 case '\n':
1431 plinno++; 1440 plinno++;
1432 needprompt = doprompt; 1441 needprompt = doprompt;
1433 break; 1442 break;
1434 1443
1435 case PEOF: 1444 case PEOF:
1436 startlinno = plinno; 1445 startlinno = plinno;
1437 synerror("EOF in backquote substitution"); 1446 synerror("EOF in backquote substitution");
1438 break; 1447 break;
1439 1448
1440 default: 1449 default:
1441 break; 1450 break;
1442 } 1451 }
1443 STPUTC(pc, pout); 1452 STPUTC(pc, pout);
1444 } 1453 }
1445done: 1454done:
 1455 if (nparen)
 1456 synerror("Missing `)'");
1446 STPUTC('\0', pout); 1457 STPUTC('\0', pout);
1447 psavelen = pout - stackblock(); 1458 psavelen = pout - stackblock();
1448 if (psavelen > 0) { 1459 if (psavelen > 0) {
1449 pstr = grabstackstr(pout); 1460 pstr = grabstackstr(pout);
1450 setinputstring(pstr, 1); 1461 setinputstring(pstr, 1);
1451 } 1462 }
1452 } 1463 }
1453 nlpp = &bqlist; 1464 nlpp = &bqlist;
1454 while (*nlpp) 1465 while (*nlpp)
1455 nlpp = &(*nlpp)->next; 1466 nlpp = &(*nlpp)->next;
1456 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); 1467 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
1457 (*nlpp)->next = NULL; 1468 (*nlpp)->next = NULL;
1458 parsebackquote = oldstyle; 1469 parsebackquote = oldstyle;