Module Name: src Committed By: rillig Date: Sun Jan 9 14:06:00 UTC 2022
Modified Files: src/usr.bin/make: for.c src/usr.bin/make/unit-tests: directive-for-escape.exp directive-for-escape.mk Log Message: make: fix crash for newline in .for value in -dp mode (since yesterday) To generate a diff of this commit: cvs rdiff -u -r1.163 -r1.164 src/usr.bin/make/for.c cvs rdiff -u -r1.12 -r1.13 \ src/usr.bin/make/unit-tests/directive-for-escape.exp \ src/usr.bin/make/unit-tests/directive-for-escape.mk Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/make/for.c diff -u src/usr.bin/make/for.c:1.163 src/usr.bin/make/for.c:1.164 --- src/usr.bin/make/for.c:1.163 Sun Jan 9 12:43:52 2022 +++ src/usr.bin/make/for.c Sun Jan 9 14:06:00 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: for.c,v 1.163 2022/01/09 12:43:52 rillig Exp $ */ +/* $NetBSD: for.c,v 1.164 2022/01/09 14:06:00 rillig Exp $ */ /* * Copyright (c) 1992, The Regents of the University of California. @@ -58,7 +58,7 @@ #include "make.h" /* "@(#)for.c 8.1 (Berkeley) 6/6/93" */ -MAKE_RCSID("$NetBSD: for.c,v 1.163 2022/01/09 12:43:52 rillig Exp $"); +MAKE_RCSID("$NetBSD: for.c,v 1.164 2022/01/09 14:06:00 rillig Exp $"); typedef struct ForLoop { @@ -367,8 +367,8 @@ AddEscaped(Buffer *cmds, Substring item, * expression like ${i} or ${i:...} or $(i) or $(i:...) with ":Uvalue". */ static void -ForLoop_SubstVarLong(ForLoop *f, Buffer *body, const char **pp, - char endc, const char **inout_mark) +ForLoop_SubstVarLong(ForLoop *f, unsigned int firstItem, Buffer *body, + const char **pp, char endc, const char **inout_mark) { size_t i; const char *start = *pp; @@ -392,7 +392,7 @@ ForLoop_SubstVarLong(ForLoop *f, Buffer */ Buf_AddBytesBetween(body, *inout_mark, start); Buf_AddStr(body, ":U"); - AddEscaped(body, f->items.words[f->nextItem + i], endc); + AddEscaped(body, f->items.words[firstItem + i], endc); *inout_mark = p; *pp = p; @@ -405,7 +405,7 @@ ForLoop_SubstVarLong(ForLoop *f, Buffer * variable expressions like $i with their ${:U...} expansion. */ static void -ForLoop_SubstVarShort(ForLoop *f, Buffer *body, +ForLoop_SubstVarShort(ForLoop *f, unsigned int firstItem, Buffer *body, const char *p, const char **inout_mark) { const char ch = *p; @@ -430,7 +430,7 @@ found: /* Replace $<ch> with ${:U<value>} */ Buf_AddStr(body, "{:U"); - AddEscaped(body, f->items.words[f->nextItem + i], '}'); + AddEscaped(body, f->items.words[firstItem + i], '}'); Buf_AddByte(body, '}'); } @@ -448,7 +448,7 @@ found: * possible to contrive a makefile where an unwanted substitution happens. */ static void -ForLoop_SubstBody(ForLoop *f, Buffer *body) +ForLoop_SubstBody(ForLoop *f, unsigned int firstItem, Buffer *body) { const char *p, *end; const char *mark; /* where the last substitution left off */ @@ -461,9 +461,11 @@ ForLoop_SubstBody(ForLoop *f, Buffer *bo if (p[1] == '{' || p[1] == '(') { char endc = p[1] == '{' ? '}' : ')'; p += 2; - ForLoop_SubstVarLong(f, body, &p, endc, &mark); + ForLoop_SubstVarLong(f, firstItem, body, + &p, endc, &mark); } else if (p[1] != '\0') { - ForLoop_SubstVarShort(f, body, p + 1, &mark); + ForLoop_SubstVarShort(f, firstItem, body, + p + 1, &mark); p += 2; } else break; @@ -482,9 +484,9 @@ For_NextIteration(ForLoop *f, Buffer *bo if (f->nextItem == f->items.len) return false; - ForLoop_SubstBody(f, body); - DEBUG1(FOR, "For: loop body:\n%s", body->data); f->nextItem += (unsigned int)f->vars.len; + ForLoop_SubstBody(f, f->nextItem - (unsigned int)f->vars.len, body); + DEBUG1(FOR, "For: loop body:\n%s", body->data); return true; } Index: src/usr.bin/make/unit-tests/directive-for-escape.exp diff -u src/usr.bin/make/unit-tests/directive-for-escape.exp:1.12 src/usr.bin/make/unit-tests/directive-for-escape.exp:1.13 --- src/usr.bin/make/unit-tests/directive-for-escape.exp:1.12 Thu Sep 2 07:02:08 2021 +++ src/usr.bin/make/unit-tests/directive-for-escape.exp Sun Jan 9 14:06:00 2022 @@ -87,6 +87,22 @@ For: loop body: . info long: ${:U" "} make: "directive-for-escape.mk" line 138: short: " " make: "directive-for-escape.mk" line 139: long: " " +For: end for 1 +For: loop body: +For: end for 1 +Parse_PushInput: .for loop in directive-for-escape.mk, line 152 +make: "directive-for-escape.mk" line 152: newline in .for value + in .for loop from directive-for-escape.mk:152 with i = " +" +For: loop body: +: ${:U" "} +SetFilenameVars: ${.PARSEDIR} = `<curdir>' ${.PARSEFILE} = `directive-for-escape.mk' +Parsing line 153: : ${:U" "} +ParseDependency(: " ") +ParseEOF: returning to file directive-for-escape.mk, line 155 +SetFilenameVars: ${.PARSEDIR} = `<curdir>' ${.PARSEFILE} = `directive-for-escape.mk' +Parsing line 155: .MAKEFLAGS: -d0 +ParseDependency(.MAKEFLAGS: -d0) make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 Index: src/usr.bin/make/unit-tests/directive-for-escape.mk diff -u src/usr.bin/make/unit-tests/directive-for-escape.mk:1.12 src/usr.bin/make/unit-tests/directive-for-escape.mk:1.13 --- src/usr.bin/make/unit-tests/directive-for-escape.mk:1.12 Sun Dec 5 11:40:03 2021 +++ src/usr.bin/make/unit-tests/directive-for-escape.mk Sun Jan 9 14:06:00 2022 @@ -1,4 +1,4 @@ -# $NetBSD: directive-for-escape.mk,v 1.12 2021/12/05 11:40:03 rillig Exp $ +# $NetBSD: directive-for-escape.mk,v 1.13 2022/01/09 14:06:00 rillig Exp $ # # Test escaping of special characters in the iteration values of a .for loop. # These values get expanded later using the :U variable modifier, and this @@ -139,4 +139,19 @@ ${closing-brace}= <closing-brace> # alte . info long: ${i} .endfor +# No error since the newline character is not actually used. +.for i in "${.newline}" +.endfor + +# Between for.c 1.161 from 2022-01-08 and before for.c 1.163 from 2022-01-09, +# a newline character in a .for loop led to a crash since at the point where +# the error message including the stack trace is printed, the body of the .for +# loop is assembled, and at that point, ForLoop.nextItem had already been +# advanced. +.MAKEFLAGS: -dp +.for i in "${.newline}" +: $i +.endfor +.MAKEFLAGS: -d0 + all: