[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCHv2] AC_COMPILE_IFELSE: Evaluate user supplied arguments
From: |
Nikolai Merinov |
Subject: |
Re: [PATCHv2] AC_COMPILE_IFELSE: Evaluate user supplied arguments |
Date: |
Sat, 09 Mar 2019 20:08:13 +0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) |
Hi Eric,
Eric Blake <address@hidden> 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 <address@hidden>
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