From c6966b323811c37acedff05b576b907b06aea5f4 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Thu, 22 Dec 2016 18:47:26 -0500 Subject: [PATCH] [SV 20513] Un-escaped # are not comments in function invocations * NEWS: Document the change, as a backward-incompatible change. * main.c (main): Add 'nocomment' to the .FEATURES variable. * read.c (remove_comments): Skip variable references during remove. (find_char_unquote): Fix comments for new STOPMAP support. * tests/scripts/features/escape: Test new escape syntax. * tests/scripts/functions/guile: Ditto. * tests/scripts/functions/shell: Ditto. --- NEWS | 14 ++++++++++++++ main.c | 2 +- read.c | 25 +++++++++++++------------ tests/scripts/features/escape | 18 ++++++++++++++++++ tests/scripts/functions/guile | 14 ++++++++++++++ tests/scripts/functions/shell | 6 ++---- 6 files changed, 62 insertions(+), 17 deletions(-) diff --git a/NEWS b/NEWS index d3059aef..0dab2ee8 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,20 @@ A complete list of bugs fixed in this version is available here: http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&set=custom +* WARNING: Backward-incompatibility! + Number signs (#) appearing inside a macro reference or function invocation + no longer introduce comments and should not be escaped with backslashes: + thus a call such as: + foo := $(shell echo '#') + is legal. Previously the number sign needed to be escaped, for example: + foo := $(shell echo '\#') + Now this latter will resolve to "\#". If you want to write makefiles + portable to both versions, assign the number sign to a variable: + C := \# + foo := $(shell echo '$C') + This was claimed to be fixed in 3.81, but wasn't, for some reason. + To detect this change search for 'nocomment' in the .FEATURES variable. + * The previous limit of 63 jobs under -jN on MS-Windows is now increased to 4095. That limit includes the subprocess started by the $(shell) function. diff --git a/main.c b/main.c index 80c17dae..aa3d80d2 100644 --- a/main.c +++ b/main.c @@ -1321,7 +1321,7 @@ main (int argc, char **argv, char **envp) some compilers (MSVC) don't like conditionals in macros. */ { const char *features = "target-specific order-only second-expansion" - " else-if shortest-stem undefine oneshell" + " else-if shortest-stem undefine oneshell nocomment" #ifndef NO_ARCHIVES " archives" #endif diff --git a/read.c b/read.c index e8b505da..26ba6f9d 100644 --- a/read.c +++ b/read.c @@ -1398,14 +1398,15 @@ eval (struct ebuffer *ebuf, int set_default) /* Remove comments from LINE. - This is done by copying the text at LINE onto itself. */ + This will also remove backslashes that escape things. + It ignores comment characters that appear inside variable references. */ static void remove_comments (char *line) { char *comment; - comment = find_char_unquote (line, MAP_COMMENT); + comment = find_char_unquote (line, MAP_COMMENT|MAP_VARIABLE); if (comment != 0) /* Cut off the line at the #. */ @@ -2224,27 +2225,27 @@ record_files (struct nameseq *filenames, const char *pattern, } } -/* Search STRING for an unquoted STOPCHAR or blank (if BLANK is nonzero). - Backslashes quote STOPCHAR, blanks if BLANK is nonzero, and backslash. - Quoting backslashes are removed from STRING by compacting it into - itself. Returns a pointer to the first unquoted STOPCHAR if there is - one, or nil if there are none. STOPCHARs inside variable references are - ignored if IGNOREVARS is true. +/* Search STRING for an unquoted STOPMAP. + Backslashes quote elements from STOPMAP and backslash. + Quoting backslashes are removed from STRING by compacting it into itself. + Returns a pointer to the first unquoted STOPCHAR if there is one, or nil if + there are none. - STOPCHAR _cannot_ be '$' if IGNOREVARS is true. */ + If MAP_VARIABLE is set, then the complete contents of variable references + are skipped, even if the contain STOPMAP characters. */ static char * -find_char_unquote (char *string, int map) +find_char_unquote (char *string, int stopmap) { unsigned int string_len = 0; char *p = string; /* Always stop on NUL. */ - map |= MAP_NUL; + stopmap |= MAP_NUL; while (1) { - while (! STOP_SET (*p, map)) + while (! STOP_SET (*p, stopmap)) ++p; if (*p == '\0') diff --git a/tests/scripts/features/escape b/tests/scripts/features/escape index bf069df2..de0ef48a 100644 --- a/tests/scripts/features/escape +++ b/tests/scripts/features/escape @@ -70,5 +70,23 @@ all: ..\foo !, '', ": '..\\foo'\n"); +# Test escaped comments in variable assignments +run_make_test(q! +self = $1 +foo := $(call self,#foo#)#foo +bar := $(call self,\#bar\#)#bar +all:;@echo '$(foo) $(bar)' +!, + '',"#foo# \\#bar\\#"); + +# Test escaped comments in variable assignments in a variable +run_make_test(q! +C = \# +self = $1 +foo := $(call self,$Cfoo$C)#foo +all:;@echo '$(foo)' +!, + '',"#foo#"); + # This tells the test driver that the perl test script executed properly. 1; diff --git a/tests/scripts/functions/guile b/tests/scripts/functions/guile index c63bec9b..415827ae 100644 --- a/tests/scripts/functions/guile +++ b/tests/scripts/functions/guile @@ -36,6 +36,20 @@ x:;@echo '$(guile #f)'; \ !, '', "\n#t\nc\n1234\nfoo\nbar\na b\na b c d 1 2 3"); +# Verify guile functions in variables -- SV 43378 +run_make_test(q! +res := $(guile #f) \ + $(guile #t) \ + $(guile #\c) \ + $(guile 1234) \ + $(guile 'foo) \ + $(guile "bar") \ + $(guile (cons 'a 'b)) \ + $(guile '(a b (c . d) 1 (2) 3)) +x:;@echo '$(res)' +!, + '', " #t c 1234 foo bar a b a b c d 1 2 3"); + # Verify the gmk-expand function run_make_test(q! VAR = $(guile (gmk-expand "$(shell echo hi)")) diff --git a/tests/scripts/functions/shell b/tests/scripts/functions/shell index 809c77fa..0a549a72 100644 --- a/tests/scripts/functions/shell +++ b/tests/scripts/functions/shell @@ -27,13 +27,11 @@ all: ; @echo PRE=$(PRE) OK=$(OK) BAD=$(BAD) # Test unescaped comment characters in shells. Savannah bug #20513 -if ($all_tests) { - run_make_test(q! +run_make_test(q! FOO := $(shell echo '#') foo: ; echo '$(FOO)' !, - '', "#\n"); -} + '', "echo '#'\n#\n"); # Test shells inside exported environment variables. # This is the test that fails if we try to put make exported variables into -- 2.47.3