From f81639309525bd1d0eac5b9c5f74a82bfa168984 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Wed, 14 May 2025 03:00:39 -0400 Subject: [PATCH] Makefile: escape single-quotes in VERBOSE $(ECHO) argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the command string run through $(call VERBOSE,…) contains a single-quote character followed by shell metacharacters, the shell executing the VERBOSE template's $(ECHO) command will attempt to interpret those metacharacters. This could be disastrous, such as if someone were to put in a Makefile recipe: $(call VERBOSE, , $(ECHO) 'Will not `rm -rf ~`') When run with V=1, which causes VERBOSE to be defined as… VERBOSE = $(ECHO) '$(2)'; $(2) …Make would evaluate the above call into: echo 'echo 'Will not `rm -rf ~`''; echo 'Will not `rm -rf ~`' And oops, there goes the neighborhood. The real-world motivating case for this fix is the sed call in the recipe for doc/index.rst in doc/Makefile. It contains a sed expression enclosed in single quotes, containing parentheses. When run through VERBOSE with V=1, the single quotes around the sed expression actually escape _out_ of the single-quoted string that is intended to be the whole command line, and you get: /bin/sh: -c: line 1: syntax error near unexpected token `(' The fix is for VERBOSE to escape any single quotes embedded in the command line argument when echoing it: VERBOSE = $(ECHO) '$(subst ','\'',$(2))'; $(2) Note that this is still wrong, as it will not do the right thing if $(2) happens to begin with a hyphen, but I didn't want to introduce a new "PRINTF" variable (or do something unsavory like calling cat with a here-doc) to squash a bug that currently has no known manifestations. Changelog-None --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 561680f5b..997265ea9 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ SORT=LC_ALL=C sort ifeq ($V,1) -VERBOSE = $(ECHO) '$(2)'; $(2) +VERBOSE = $(ECHO) '$(subst ','\'',$(2))'; $(2) else VERBOSE = $(ECHO) $(1); $(2) endif