_AC_INIT_PACKAGE was woefully underquoted when it tried to convert $1 into AC_PACKAGE_TARNAME; several other places were likewise suspect in their use of AC_PACKAGE variables. The first argument to AC_INIT makes more sense as a literal package name that should not undergo further m4 expansion.
Then _AC_INIT_LITERAL was tripping up on a limitation of m4_expand coupled with autoconf's insanity of re-exposing 'changequote' into the macro namespace (rather than keeping it m4_changequote, like autotest and other sane m4sh clients). There is just no way to safely expand a nested changequote within m4_expand, but with quadrigraphs and other workarounds, it should never be necessary (after all, we document that use of changequote is dangerous). It might be nicer if m4 had pushquote/popquote; oh well. * lib/autoconf/general.m4 (_AC_INIT_PACKAGE): Don't expand $1. (_AC_INIT_LITERAL): Work around m4_expand limitation. (_AC_INIT_NOTICE, _AC_INIT_DEFAULTS, _AC_INIT_HELP) (_AC_INIT_VERSION, _AC_INIT_CONFIG_LOG): Don't expand AC_PACKAGE_*. * lib/autoconf/headers.m4 (_AC_CHECK_HEADER_MONGREL_BODY): Likewise. * lib/autoconf/status.m4 (_AC_OUTPUT_CONFIG_STATUS): Likewise. * lib/m4sugar/m4sugar.m4 (m4_expand): Protect against infinite recursion. * tests/tools.at (package with m4 macro in name): New test. Reported by Stefano Lattarini. Signed-off-by: Eric Blake <[email protected]> --- The test now passes, but I have not pushed this yet. Note that this is a subtle semantic change. It used to be that you could do: m4_define([pkg_name], [foo]) AC_INIT([pkg_name], [1.0]) and that would result in AC_SUBST of PACKAGE_NAME=foo With this patch, it results in PACKAGE_NAME=pkg_name. Note that this patch still has an implicit limitation that you can't do AC_INIT([m4_...]) for many m4sugar macro names; but as the m4_ prefix is less likely to appear in a real package name, I'm not as worried (after all, m4 can't code around every possible string without an insane amount of overhead, so focusing on efficiently handling just the majority of useful strings is okay). However, we were inconsistent; at least _AS_DETECT_BETTER_SHELL was already using m4_defn([AC_PACKAGE_NAME]), which would report pkg_name in the above situation rather than foo. That alone argues that we should either always expand or always treat as a literal string; this patch goes for the literal string aspect. I don't see too much harm in making this change, and stating that the arguments to AC_INIT are never re-expanded for macros by autoconf itself. For most packages it won't matter - you don't define macros for your package name; for automake, it will avoid the testsuite failures encountered when the test name included an m4 builtin that later became an AC_INIT argument. And for computation purposes, you can _always_ do this, pre- and post-patch, to get PACKAGE_NAME=foo: m4_define([pkg_name], [foo]) AC_INIT(pkg_name, [1.0]) I think that I need to also touch up docs/autoconf.texi and NEWS before pushing this, in case someone really was expecting macro invocation after the fact. ChangeLog | 16 ++++++++++++ lib/autoconf/general.m4 | 62 +++++++++++++++++++++++++++------------------- lib/autoconf/headers.m4 | 2 +- lib/autoconf/status.m4 | 14 ++++++---- lib/m4sugar/m4sugar.m4 | 2 + tests/tools.at | 24 ++++++++++++++++++ 6 files changed, 87 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 30dfced..16d01d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-03-16 Eric Blake <[email protected]> + + AC_INIT: properly quote package name containing m4 macro + * lib/autoconf/general.m4 (_AC_INIT_PACKAGE): Don't expand $1. + (_AC_INIT_LITERAL): Work around m4_expand limitation. + (_AC_INIT_NOTICE, _AC_INIT_DEFAULTS, _AC_INIT_HELP) + (_AC_INIT_VERSION, _AC_INIT_CONFIG_LOG): Don't expand + AC_PACKAGE_*. + * lib/autoconf/headers.m4 (_AC_CHECK_HEADER_MONGREL_BODY): + Likewise. + * lib/autoconf/status.m4 (_AC_OUTPUT_CONFIG_STATUS): Likewise. + * lib/m4sugar/m4sugar.m4 (m4_expand): Protect against infinite + recursion. + * tests/tools.at (package with m4 macro in name): New test. + Reported by Stefano Lattarini. + 2011-03-08 Colin Watson <[email protected]> (tiny change) Ralf Wildenhues <[email protected]> diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4 index dd20e71..7b8c873 100644 --- a/lib/autoconf/general.m4 +++ b/lib/autoconf/general.m4 @@ -227,10 +227,14 @@ AU_ALIAS([AC_HELP_STRING], [AS_HELP_STRING]) # Reject STRING if it contains newline, or if it cannot be used as-is # in single-quoted strings, double-quoted strings, and quoted and # unquoted here-docs. +# +# Special case changequote to work around m4_expand limitations. m4_define([_AC_INIT_LITERAL], +[m4_rename([changequote], [_m4_changequote])]dnl [m4_if(m4_index(m4_translit([[$1]], [ ""], ['']), ['])AS_LITERAL_HEREDOC_IF([$1], [-]), [-1-], [], - [m4_warn([syntax], [AC_INIT: not a literal: $1])])]) + [m4_warn([syntax], [AC_INIT: not a literal: $1])])]dnl +[m4_rename([_m4_changequote], [changequote])]) # _AC_INIT_PACKAGE(PACKAGE-NAME, VERSION, BUG-REPORT, [TARNAME], [URL]) # --------------------------------------------------------------------- @@ -241,12 +245,10 @@ _AC_INIT_LITERAL([$3]) m4_ifndef([AC_PACKAGE_NAME], [m4_define([AC_PACKAGE_NAME], [$1])]) m4_ifndef([AC_PACKAGE_TARNAME], - [m4_define([AC_PACKAGE_TARNAME], - m4_default([$4], - [m4_bpatsubst(m4_tolower(m4_bpatsubst([[$1]], - [GNU ])), - [[^_abcdefghijklmnopqrstuvwxyz0123456789]], - [-])]))]) + [m4_define([AC_PACKAGE_TARNAME], + m4_if([$4], [], + [m4_translit(_AS_TR_SH_LITERAL(m4_bpatsubst([[[$1]]], + [^\(..\)GNU ], [\1])), [_A-Z], [-a-z])], [[$4]]))]) m4_ifndef([AC_PACKAGE_VERSION], [m4_define([AC_PACKAGE_VERSION], [$2])]) m4_ifndef([AC_PACKAGE_STRING], @@ -341,12 +343,12 @@ m4_define([_AC_INIT_NOTICE], [m4_divert_text([HEADER-COMMENT], [@%:@ Guess values for system-dependent variables and create Makefiles. @%:@ Generated by m4_PACKAGE_STRING[]dnl -m4_ifset([AC_PACKAGE_STRING], [ for AC_PACKAGE_STRING]).]) +m4_ifset([AC_PACKAGE_STRING], [ for m4_defn([AC_PACKAGE_STRING])]).]) m4_ifset([AC_PACKAGE_BUGREPORT], [m4_divert_text([HEADER-COMMENT], [@%:@ -@%:@ Report bugs to <AC_PACKAGE_BUGREPORT>.])]) +@%:@ Report bugs to <m4_defn([AC_PACKAGE_BUGREPORT])>.])]) ]) @@ -415,17 +417,23 @@ AC_SUBST([PATH_SEPARATOR])dnl # Identity of this package. AC_SUBST([PACKAGE_NAME], - [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])])dnl + m4_ifdef([AC_PACKAGE_NAME], + ['m4_dquote(m4_defn([AC_PACKAGE_NAME]))']))dnl AC_SUBST([PACKAGE_TARNAME], - [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])])dnl + m4_ifdef([AC_PACKAGE_TARNAME], + ['m4_dquote(m4_defn([AC_PACKAGE_TARNAME]))']))dnl AC_SUBST([PACKAGE_VERSION], - [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])])dnl + m4_ifdef([AC_PACKAGE_VERSION], + ['m4_dquote(m4_defn([AC_PACKAGE_VERSION]))']))dnl AC_SUBST([PACKAGE_STRING], - [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])])dnl + m4_ifdef([AC_PACKAGE_STRING], + ['m4_dquote(m4_defn([AC_PACKAGE_STRING]))']))dnl AC_SUBST([PACKAGE_BUGREPORT], - [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])dnl + m4_ifdef([AC_PACKAGE_BUGREPORT], + ['m4_dquote(m4_defn([AC_PACKAGE_BUGREPORT]))']))dnl AC_SUBST([PACKAGE_URL], - [m4_ifdef([AC_PACKAGE_URL], ['AC_PACKAGE_URL'])])dnl + m4_ifdef([AC_PACKAGE_URL], + ['m4_dquote(m4_defn([AC_PACKAGE_URL]))']))dnl m4_divert_pop([DEFAULTS])dnl m4_wrap_lifo([m4_divert_text([DEFAULTS], @@ -588,9 +596,9 @@ AC_SUBST([sharedstatedir], ['${prefix}/com'])dnl AC_SUBST([localstatedir], ['${prefix}/var'])dnl AC_SUBST([includedir], ['${prefix}/include'])dnl AC_SUBST([oldincludedir], ['/usr/include'])dnl -AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME], +AC_SUBST([docdir], m4_ifset([AC_PACKAGE_TARNAME], ['${datarootdir}/doc/${PACKAGE_TARNAME}'], - ['${datarootdir}/doc/${PACKAGE}'])])dnl + [['${datarootdir}/doc/${PACKAGE}']]))dnl AC_SUBST([infodir], ['${datarootdir}/info'])dnl AC_SUBST([htmldir], ['${docdir}'])dnl AC_SUBST([dvidir], ['${docdir}'])dnl @@ -1019,7 +1027,7 @@ if test "$ac_init_help" = "long"; then # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures m4_ifset([AC_PACKAGE_STRING], - [AC_PACKAGE_STRING], + [m4_defn([AC_PACKAGE_STRING])], [this package]) to adapt to many kinds of systems. Usage: $[0] [[OPTION]]... [[VAR=VALUE]]... @@ -1070,7 +1078,7 @@ Fine tuning of the installation directories: --mandir=DIR man documentation [DATAROOTDIR/man] ]AS_HELP_STRING([--docdir=DIR], [documentation root ]@<:@DATAROOTDIR/doc/m4_ifset([AC_PACKAGE_TARNAME], - [AC_PACKAGE_TARNAME], [PACKAGE])@:>@)[ + [m4_defn([AC_PACKAGE_TARNAME])], [PACKAGE])@:>@)[ --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1108,16 +1116,17 @@ fi if test -n "$ac_init_help"; then m4_ifset([AC_PACKAGE_STRING], [ case $ac_init_help in - short | recursive ) echo "Configuration of AC_PACKAGE_STRING:";; + short | recursive ) echo "Configuration of m4_defn([AC_PACKAGE_STRING]):";; esac]) cat <<\_ACEOF m4_divert_pop([HELP_ENABLE])dnl m4_divert_push([HELP_END])dnl -Report bugs to m4_ifset([AC_PACKAGE_BUGREPORT], [<AC_PACKAGE_BUGREPORT>], +Report bugs to m4_ifset([AC_PACKAGE_BUGREPORT], + [<m4_defn([AC_PACKAGE_BUGREPORT])>], [the package provider]).dnl m4_ifdef([AC_PACKAGE_NAME], [m4_ifset([AC_PACKAGE_URL], [ -AC_PACKAGE_NAME home page: <AC_PACKAGE_URL>.])dnl +m4_defn([AC_PACKAGE_NAME]) home page: <m4_defn([AC_PACKAGE_URL])>.])dnl m4_if(m4_index(m4_defn([AC_PACKAGE_NAME]), [GNU ]), [0], [ General help using GNU software: <http://www.gnu.org/gethelp/>.])]) _ACEOF @@ -1158,8 +1167,8 @@ m4_define([_AC_INIT_VERSION], [m4_divert_text([VERSION_BEGIN], [if $ac_init_version; then cat <<\_ACEOF -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])configure[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +m4_ifset([AC_PACKAGE_NAME], [m4_defn([AC_PACKAGE_NAME]) ])configure[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ m4_defn([AC_PACKAGE_VERSION])]) generated by m4_PACKAGE_STRING]) m4_divert_text([VERSION_END], [_ACEOF @@ -1178,8 +1187,9 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])dnl -$as_me[]m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]), which was +It was created by m4_ifset([AC_PACKAGE_NAME], [m4_defn([AC_PACKAGE_NAME]) ])dnl +$as_me[]m4_ifset([AC_PACKAGE_VERSION], + [ m4_defn([AC_PACKAGE_VERSION])]), which was generated by m4_PACKAGE_STRING. Invocation command line was $ $[0] $[@] diff --git a/lib/autoconf/headers.m4 b/lib/autoconf/headers.m4 index 4b02832..5e315ae 100644 --- a/lib/autoconf/headers.m4 +++ b/lib/autoconf/headers.m4 @@ -107,7 +107,7 @@ case $ac_header_compiler:$ac_header_preproc:$ac_[]_AC_LANG_ABBREV[]_preproc_warn AC_MSG_WARN([$[]2: section "Present But Cannot Be Compiled"]) AC_MSG_WARN([$[]2: proceeding with the compiler's result]) m4_ifset([AC_PACKAGE_BUGREPORT], -[m4_n([( AS_BOX([Report this to ]AC_PACKAGE_BUGREPORT) +[m4_n([( AS_BOX([Report this to ]m4_defn([AC_PACKAGE_BUGREPORT])) ) | sed "s/^/$as_me: WARNING: /" >&2])])dnl ;; esac diff --git a/lib/autoconf/status.m4 b/lib/autoconf/status.m4 index 46a0341..46155bd 100644 --- a/lib/autoconf/status.m4 +++ b/lib/autoconf/status.m4 @@ -1335,8 +1335,9 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])dnl -$as_me[]m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]), which was +This file was extended by m4_ifset([AC_PACKAGE_NAME], + [m4_defn([AC_PACKAGE_NAME]) ])$as_me[]m4_ifset([AC_PACKAGE_VERSION], + [ m4_defn([AC_PACKAGE_VERSION])]), which was generated by m4_PACKAGE_STRING. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -1423,10 +1424,11 @@ m4_ifdef([_AC_SEEN_CONFIG(COMMANDS)], $config_commands ])dnl -Report bugs to m4_ifset([AC_PACKAGE_BUGREPORT], [<AC_PACKAGE_BUGREPORT>], +Report bugs to m4_ifset([AC_PACKAGE_BUGREPORT], + [<m4_defn([AC_PACKAGE_BUGREPORT])>], [the package provider]).dnl m4_ifdef([AC_PACKAGE_NAME], [m4_ifset([AC_PACKAGE_URL], [ -AC_PACKAGE_NAME home page: <AC_PACKAGE_URL>.])dnl +m4_defn([AC_PACKAGE_NAME]) home page: <m4_defn([AC_PACKAGE_URL])>.])dnl m4_if(m4_index(m4_defn([AC_PACKAGE_NAME]), [GNU ]), [0], [ General help using GNU software: <http://www.gnu.org/gethelp/>.])])" @@ -1434,8 +1436,8 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`AS_ECHO(["$ac_configure_args"]) | sed 's/^ //; s/[[\\""\`\$]]/\\\\&/g'`" ac_cs_version="\\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.status[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +m4_ifset([AC_PACKAGE_NAME], [m4_defn([AC_PACKAGE_NAME]) ])config.status[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ m4_defn([AC_PACKAGE_VERSION])]) configured by $[0], generated by m4_PACKAGE_STRING, with options \\"\$ac_cs_config\\" diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4 index 00f1f4a..c053303 100644 --- a/lib/m4sugar/m4sugar.m4 +++ b/lib/m4sugar/m4sugar.m4 @@ -915,6 +915,8 @@ m4_define([m4_echo], [$@]) # open-quote delimiter. We must also ignore the slop from the # previous try. The final macro is thus half line-noise, half art. m4_define([m4_expand], +[m4_if(m4_index([$1], m4_ifdef([changequote], [], [[m4_]])[changequote]), + [-1], [], [m4_fatal([$0: cannot call changequote inside m4_expand])])]dnl [m4_pushdef([m4_divert], _m4_defn([_m4_divert_unsafe]))]dnl [m4_pushdef([m4_divert_push], _m4_defn([_m4_divert_unsafe]))]dnl [m4_chomp(_$0([$1 diff --git a/tests/tools.at b/tests/tools.at index 0ccb387..cef6c47 100644 --- a/tests/tools.at +++ b/tests/tools.at @@ -1335,3 +1335,27 @@ END done AT_CLEANUP + +# package with m4 macro in name +# ----------------------------- + +AT_SETUP([package with m4 macro in name]) + +dnl Why did autoconf ever re-expose the m4 builtins without the m4_ prefix? +dnl In 2.68, this would create PACKAGE_NAME='10-disaster'. +AT_DATA_M4SH([configure.ac], +[[AC_INIT([divnum-disaster], [1.0]) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK([[grep [0-9]-disaster configure]], [1]) + +dnl Even worse, changequote is a nightmare waiting to happen. +dnl In Autoconf 2.68, this would exceed recursion limits. +AT_DATA_M4SH([configure.ac], +[[AC_INIT([perl-changequote-helper], [1.0]) +]]) + +AT_CHECK_AUTOCONF + +AT_CLEANUP -- 1.7.4
