Re: [PATCHv2] AC_COMPILE_IFELSE: Evaluate user supplied arguments

Nikolai Merinov <[email protected]>
Newsgroups gmane.comp.sysutils.autoconf.patches
Message-ID <[email protected]>
Hi Eric,

Eric Blake <[email protected]> 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
0001-AC_COMPILE_IFELSE-Evaluate-user-supplied-arguments.patch (text/x-patch, 2.8 KB)
From ce3a819f067c9da804081f8e659596ad384ff3d3 Mon Sep 17 00:00:00 2001
From: Nikolai Merinov <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.