Hi Eric, Eric Blake <ebl...@redhat.com> writes:
> On 3/7/19 11:33 AM, Nikolai Merinov wrote: >> In the following call sequence >>> ./configure CPPFLAGS='-DVARIABLE=\"string\"' && make >> compilation with the `AC_COMPILE_IFELSE' macro and with the `make' >> command should use same compilation commands. It means that the >> `AC_COMPILE_IFELSE' macro should evaluate the `ac_compile` variable >> twice in order to evaluate user-supplied variables. > > eval'ing user-supplied text can be dangerous, as the user can supply > arbitrary shell code if their text is not carefully sanitized. > > I'm not quite sure what you are trying to accomplish: Given a command > line (or environment variable, since CPPFLAGS is precious), are you > trying to have user input of: > > CPPFLAGS='-DVARIABLE=\"string\"' > > result in the Makefile using: > > CPPFLAGS = -DVARIABLE="string" No, resulting makefile will be the following: CPPFLAGS = -DVARIABLE=\"string\" because signle-quotes preserve the literal value of each character within the single-quotes. You can check the following code: configure.ac AC_INIT([Example application], [0.1]) AM_INIT_AUTOMAKE AC_PROG_CC # CPPFLAGS='-DVARIABLE="string"' required AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [printf("%s\n", VARIABLE)])], [], [AC_MSG_ERROR([compiling trivial program failed])]) AC_CONFIG_FILES(Makefile) AC_OUTPUT Makefile.am bin_PROGRAMS = prog prog_SOURCES = main.c main.c #include <stdio.h> int main() { /* CPPFLAGS='-DVARIABLE=\"string\"' required */ printf("%s\n", VARIABLE); return 0; } We have a same code in the AC_COMPILE_IFELSE call and in the main.c file, but it is impossible to configure and compile a code with the same CPPFLAGS value. > > (which would compile as if written: > #define VARIABLE string > because make expands $(CPPFLAGS) before invoking sh that eats the ") or in: > > CPPFLAGS = -DVARIABLE=\"string\" > > (which would compile as if written: > #define VARIABLE "string" > because sh eats the \ but leaves the ") > > At which point, are you arguing that if make is going to pass through > another shell and eat a layer of quotation, then configure should do > likewise for any use of those same variables? > >> +++ b/tests/compile.at >> @@ -301,6 +301,17 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return 2])], >> AT_CHECK_AUTOCONF >> AT_CHECK_CONFIGURE([-q]) >> >> +AT_DATA([configure.ac], >> +[[AC_INIT >> +AC_PROG_CC >> +test x$GCC = xyes && CFLAGS='"-Wall"' > > Okay, this helps - it looks like you are indeed arguing that the > Makefile will end up with: > > CFLAGS = "-Wall" > > but those quotes get eaten by shell; so our use of ${CFLAGS} during > configure should use the same level of quotation stripping as what the > resulting makefile will. > > Your patch could use a NEWS entry for the change. Added. New patch attached. Regards, Nikolai
>From ce3a819f067c9da804081f8e659596ad384ff3d3 Mon Sep 17 00:00:00 2001 From: Nikolai Merinov <nikolai.meri...@member.fsf.org> Date: Thu, 7 Mar 2019 22:33:13 +0500 Subject: [PATCH] AC_COMPILE_IFELSE: Evaluate user supplied arguments In the following call sequence > ./configure CPPFLAGS='-DVARIABLE=\"string\"' && make compilation with the `AC_COMPILE_IFELSE' macro and with the `make' command should use same compilation commands. It means that the `AC_COMPILE_IFELSE' macro should evaluate the `ac_compile` variable twice in order to evaluate user-supplied variables. * lib/autoconf/general.m4 (_AC_DO_STDERR): Reuse `_AC_DO_ECHO' trick to evaluate arguments twice if compile string have no '\"', '`', or '\\' symbols. * tests/compile.at: Add test for CFLAGS evaluation. --- NEWS | 5 +++++ lib/autoconf/general.m4 | 11 +++++++++-- tests/compile.at | 11 +++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index efade585..4ac8d683 100644 --- a/NEWS +++ b/NEWS @@ -123,6 +123,11 @@ GNU Autoconf NEWS - User visible changes. use with multiple languages, rather than forcing all checks in the language used by the first encounter of the macro. +- The _AC_DO_STDERR macro now evaluate a COMMAND argument twice. This + change consolidate behavior for user-supplied arguments between the + AC_COMPILE_IFELSE and AC_LINK_IFELSE macros and compilation commands + used in makefiles. + ** Man pages for config.guess and config.sub are no longer provided. They were moved to the master source tree for config.guess and config.sub. diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4 index e1d82b54..0e816f4b 100644 --- a/lib/autoconf/general.m4 +++ b/lib/autoconf/general.m4 @@ -2456,8 +2456,15 @@ AC_DEFUN([_AC_DO], # ---------------------- # Like _AC_RUN_LOG_STDERR, but eval (instead of running) COMMAND. AC_DEFUN([_AC_DO_STDERR], -[_AC_RUN_LOG_STDERR([eval "$1"], - [_AC_DO_ECHO([$1])])]) +[m4_if([$1], [$ac_do_stderr], [], [ac_do_stderr="$1" +])]dnl +[[case "(($ac_do_stderr" in + *\"* | *\`* | *\\*) ac_do_stderr_command=\$ac_do_stderr;; + *) ac_do_stderr_command=$ac_do_stderr;; +esac +eval ac_do_stderr_command="\"$ac_do_stderr_command\""] +_AC_RUN_LOG_STDERR([eval "$ac_do_stderr_command"], + [_AC_DO_ECHO([$ac_do_stderr])])]) # _AC_DO_VAR(VARIABLE) diff --git a/tests/compile.at b/tests/compile.at index 29374529..9af8cb38 100644 --- a/tests/compile.at +++ b/tests/compile.at @@ -301,6 +301,17 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return 2])], AT_CHECK_AUTOCONF AT_CHECK_CONFIGURE([-q]) +AT_DATA([configure.ac], +[[AC_INIT +AC_PROG_CC +test x$GCC = xyes && CFLAGS='"-Wall"' +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return 0])], [], + [AC_MSG_ERROR([compiling trivial program failed])]) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE([-q]) + AT_CLEANUP ## --------------- ## -- 2.20.0