Sun Jul 19 19:27:08 2020 UTC ()
make(1): fix off-by-one error in :C modifier

Previously this off-by-one error had invoked undefined behavior.
Until today there was no corresponding unit test though.


(rillig)
diff -r1.270 -r1.271 src/usr.bin/make/var.c
diff -r1.16 -r1.17 src/usr.bin/make/unit-tests/modmisc.exp

cvs diff -r1.270 -r1.271 src/usr.bin/make/var.c (expand / switch to unified diff)

--- src/usr.bin/make/var.c 2020/07/19 18:35:53 1.270
+++ src/usr.bin/make/var.c 2020/07/19 19:27:08 1.271
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.270 2020/07/19 18:35:53 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.271 2020/07/19 19:27:08 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 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 * Adam de Boor. 8 * Adam de Boor.
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.
@@ -59,34 +59,34 @@ @@ -59,34 +59,34 @@
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE. 68 * SUCH DAMAGE.
69 */ 69 */
70 70
71#ifndef MAKE_NATIVE 71#ifndef MAKE_NATIVE
72static char rcsid[] = "$NetBSD: var.c,v 1.270 2020/07/19 18:35:53 rillig Exp $"; 72static char rcsid[] = "$NetBSD: var.c,v 1.271 2020/07/19 19:27:08 rillig Exp $";
73#else 73#else
74#include <sys/cdefs.h> 74#include <sys/cdefs.h>
75#ifndef lint 75#ifndef lint
76#if 0 76#if 0
77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; 77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
78#else 78#else
79__RCSID("$NetBSD: var.c,v 1.270 2020/07/19 18:35:53 rillig Exp $"); 79__RCSID("$NetBSD: var.c,v 1.271 2020/07/19 19:27:08 rillig Exp $");
80#endif 80#endif
81#endif /* not lint */ 81#endif /* not lint */
82#endif 82#endif
83 83
84/*- 84/*-
85 * var.c -- 85 * var.c --
86 * Variable-handling functions 86 * Variable-handling functions
87 * 87 *
88 * Interface: 88 * Interface:
89 * Var_Set Set the value of a variable in the given 89 * Var_Set Set the value of a variable in the given
90 * context. The variable is created if it doesn't 90 * context. The variable is created if it doesn't
91 * yet exist. The value and variable name need not 91 * yet exist. The value and variable name need not
92 * be preserved. 92 * be preserved.
@@ -1568,27 +1568,27 @@ VarRESubstitute(GNode *ctx MAKE_ATTR_UNU @@ -1568,27 +1568,27 @@ VarRESubstitute(GNode *ctx MAKE_ATTR_UNU
1568 1568
1569 if (*rp == '&') { 1569 if (*rp == '&') {
1570 n = 0; 1570 n = 0;
1571 errstr[0] = '&'; 1571 errstr[0] = '&';
1572 errstr[1] = '\0'; 1572 errstr[1] = '\0';
1573 } else { 1573 } else {
1574 n = rp[1] - '0'; 1574 n = rp[1] - '0';
1575 errstr[0] = '\\'; 1575 errstr[0] = '\\';
1576 errstr[1] = rp[1]; 1576 errstr[1] = rp[1];
1577 errstr[2] = '\0'; 1577 errstr[2] = '\0';
1578 rp++; 1578 rp++;
1579 } 1579 }
1580 1580
1581 if (n > pat->nsub) { 1581 if (n >= pat->nsub) {
1582 Error("No subexpression %s", &errstr[0]); 1582 Error("No subexpression %s", &errstr[0]);
1583 subbuf = ""; 1583 subbuf = "";
1584 sublen = 0; 1584 sublen = 0;
1585 } else if ((pat->matches[n].rm_so == -1) && 1585 } else if ((pat->matches[n].rm_so == -1) &&
1586 (pat->matches[n].rm_eo == -1)) { 1586 (pat->matches[n].rm_eo == -1)) {
1587 Error("No match for subexpression %s", &errstr[0]); 1587 Error("No match for subexpression %s", &errstr[0]);
1588 subbuf = ""; 1588 subbuf = "";
1589 sublen = 0; 1589 sublen = 0;
1590 } else { 1590 } else {
1591 subbuf = wp + pat->matches[n].rm_so; 1591 subbuf = wp + pat->matches[n].rm_so;
1592 sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so; 1592 sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so;
1593 } 1593 }
1594 1594

cvs diff -r1.16 -r1.17 src/usr.bin/make/unit-tests/modmisc.exp (expand / switch to unified diff)

--- src/usr.bin/make/unit-tests/modmisc.exp 2020/07/19 17:24:22 1.16
+++ src/usr.bin/make/unit-tests/modmisc.exp 2020/07/19 19:27:08 1.17
@@ -42,23 +42,31 @@ mod-subst-dollar:$4: @@ -42,23 +42,31 @@ mod-subst-dollar:$4:
42mod-subst-dollar:$5: 42mod-subst-dollar:$5:
43mod-subst-dollar:$6: 43mod-subst-dollar:$6:
44mod-subst-dollar:$7: 44mod-subst-dollar:$7:
45mod-subst-dollar:$8: 45mod-subst-dollar:$8:
46mod-subst-dollar:U8: 46mod-subst-dollar:U8:
47mod-subst-dollar:$$$$: 47mod-subst-dollar:$$$$:
48mod-loop-dollar:1: 48mod-loop-dollar:1:
49mod-loop-dollar:${word}: 49mod-loop-dollar:${word}:
50mod-loop-dollar:$3$: 50mod-loop-dollar:$3$:
51mod-loop-dollar:$${word}$: 51mod-loop-dollar:$${word}$:
52mod-loop-dollar:$$5$$: 52mod-loop-dollar:$$5$$:
53mod-loop-dollar:$$${word}$$: 53mod-loop-dollar:$$${word}$$:
54mod-C-limits:00-ok:1 2323 45456 54mod-C-limits:00-ok:1 2323 45456
 55make: No subexpression \1
 56make: No subexpression \1
 57make: No subexpression \1
 58make: No subexpression \1
55mod-C-limits:11-missing:1 6 59mod-C-limits:11-missing:1 6
56mod-C-limits:11-ok:1 22 446 60mod-C-limits:11-ok:1 22 446
57make: No subexpression \2 61make: No subexpression \2
58make: No subexpression \2 62make: No subexpression \2
59make: No subexpression \2 63make: No subexpression \2
60make: No subexpression \2 64make: No subexpression \2
61mod-C-limits:22-missing:1 6 65mod-C-limits:22-missing:1 6
 66make: No subexpression \2
 67make: No subexpression \2
 68make: No subexpression \2
 69make: No subexpression \2
62mod-C-limits:22-missing:1 6 70mod-C-limits:22-missing:1 6
63mod-C-limits:22-ok:1 33 556 71mod-C-limits:22-ok:1 33 556
64exit status 0 72exit status 0