[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/2] Trim whitespace from arguments of AC_INIT (#107986)
From: |
Zack Weinberg |
Subject: |
[PATCH 1/2] Trim whitespace from arguments of AC_INIT (#107986) |
Date: |
Fri, 14 Aug 2020 14:44:06 -0400 |
Specifically, all five arguments, if present, are passed through
m4_normalize before doing anything else with them. For instance,
AC_INIT([ GNU Hello ], [1.0]) is now equivalent to
AC_INIT([GNU Hello], [1.0]).
As a consequence, newlines in the arguments to AC_INIT are now
converted to spaces and no longer trigger warnings.
Also, diagnose inappropriate contents of the fourth and fifth
arguments as well as the first three. The fifth argument should be
“usable as-is in single- and double-quoted strings and quoted and
unquoted here-docs,” like the first three. (This is the check
performed by _AC_INIT_LITERAL.) The fourth argument (TARNAME) is used
to construct filenames, so apply an even more stringent test, namely
AS_LITERAL_WORD_IF.
Suggested by David A. Wheeler, who submitted a patch, but I didn’t
wind up using any of his code.
* lib/autoconf/general.m4 (_AC_INIT_LITERAL): Not necessary to check
for newlines anymore.
(_AC_INIT_PACKAGE): Pass all five arguments through m4_normalize
before doing anything else with them. New warning: apply
_AC_INIT_LITERAL to fifth argument (URL). New warning: complain
if fourth argument (TARNAME) is not a literal word according to
AS_LITERAL_WORD_IF. Simplify a conditional by using m4_default.
* tests/base.at (AC_INIT with unusual version strings): Adjust to
match above changes, add more subtests.
---
NEWS | 11 +++++++
doc/autoconf.texi | 7 +++-
lib/autoconf/general.m4 | 70 ++++++++++++++++++++++++++-------------
tests/base.at | 73 ++++++++++++++++++++++++++++++++++++-----
4 files changed, 130 insertions(+), 31 deletions(-)
diff --git a/NEWS b/NEWS
index 000570e0..e0cdd069 100644
--- a/NEWS
+++ b/NEWS
@@ -194,6 +194,17 @@ GNU Autoconf NEWS - User visible changes.
- AC_FC_LINE_LENGTH now documents the maximum portable length of
"unlimited" Fortran source code lines to be 250 columns, not 254.
+- AC_INIT now trims extra white space from its arguments. For instance,
+
+ AC_INIT([ GNU Hello ], [1.0])
+
+ will set PACKAGE_NAME to “GNU Hello”.
+
+- AC_INIT will now issue warnings (in the “syntax” category) for a
+ non-literal URL argument, and for a TARNAME argument which is either
+ non-literal or contains characters that should not be used in file
+ names (e.g. ‘*’).
+
* Noteworthy changes in release 2.69 (2012-04-24) [stable]
** Autoconf now requires perl 5.6 or better (but generated configure
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 8e563bf8..4b90debb 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -1890,7 +1890,7 @@ Initializing configure
other than alphanumerics and underscores are changed to @samp{-}. If
provided, @var{url} should be the home page for the package.
-The arguments of @code{AC_INIT} must be static, i.e., there should not
+All the arguments of @code{AC_INIT} must be static, i.e., there should not
be any shell computation, quotes, or newlines, but they can be computed
by M4. This is because the package information strings are expanded at
M4 time into several contexts, and must give the same text at shell time
@@ -1901,6 +1901,11 @@ Initializing configure
Autoconf does just that, for all builds of the development tree made
between releases).
+The @var{tarname} argument is used to construct filenames.
+In addition to being static, it should not contain wildcard
+characters, white space, or anything else that could be troublesome
+as part of a file or directory name.
+
The following M4 macros (e.g., @code{AC_PACKAGE_NAME}), output variables
(e.g., @code{PACKAGE_NAME}), and preprocessor symbols (e.g.,
@code{PACKAGE_NAME}), are defined by @code{AC_INIT}:
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index 8436d8c3..4d5f021d 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -224,40 +224,66 @@ AU_ALIAS([AC_HELP_STRING], [AS_HELP_STRING])
# _AC_INIT_LITERAL(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.
+# Reject STRING if it cannot be used as-is in single-quoted strings,
+# double-quoted strings, and quoted and unquoted here-docs.
m4_define([_AC_INIT_LITERAL],
-[m4_if(m4_index(m4_translit([[$1]], [
-""], ['']), ['])AS_LITERAL_HEREDOC_IF([$1], [-]), [-1-], [],
- [m4_warn([syntax], [AC_INIT: not a literal: $1])])])
+[m4_if(m4_index(m4_translit([[$1]], [""], ['']),
+ ['])AS_LITERAL_HEREDOC_IF([$1], [-]),
+ [-1-], [],
+ [m4_warn([syntax], [AC_INIT: not a literal: "$1"])])])
# _AC_INIT_PACKAGE(PACKAGE-NAME, VERSION, BUG-REPORT, [TARNAME], [URL])
# ---------------------------------------------------------------------
m4_define([_AC_INIT_PACKAGE],
-[_AC_INIT_LITERAL([$1])
-_AC_INIT_LITERAL([$2])
-_AC_INIT_LITERAL([$3])
+[m4_pushdef([_ac_init_NAME], m4_normalize([$1]))
+m4_pushdef([_ac_init_VERSION], m4_normalize([$2]))
+m4_pushdef([_ac_init_BUGREPORT], m4_normalize([$3]))
+m4_pushdef([_ac_init_TARNAME], m4_normalize([$4]))
+m4_pushdef([_ac_init_URL], m4_normalize([$5]))
+# NAME, VERSION, BUGREPORT, and URL should all be safe for use in shell
+# strings of all kinds.
+_AC_INIT_LITERAL(m4_defn([_ac_init_NAME]))
+_AC_INIT_LITERAL(m4_defn([_ac_init_VERSION]))
+_AC_INIT_LITERAL(m4_defn([_ac_init_BUGREPORT]))
+_AC_INIT_LITERAL(m4_defn([_ac_init_URL]))
+# TARNAME is even more constrained: it should not contain any shell
+# metacharacters or whitespace, because it is used to construct
+# filenames.
+AS_LITERAL_WORD_IF(m4_defn([_ac_init_TARNAME]), [],
+ [m4_warn([syntax],
+ [AC_INIT: unsafe as a filename: "]m4_defn([_ac_init_TARNAME])["])])
+#
+# These do not use m4_copy because we don't want to copy the pushdef stack.
m4_ifndef([AC_PACKAGE_NAME],
- [m4_define([AC_PACKAGE_NAME], [$1])])
+ [m4_define([AC_PACKAGE_NAME],
+ m4_defn([_ac_init_NAME]))])
+m4_ifndef([AC_PACKAGE_VERSION],
+ [m4_define([AC_PACKAGE_VERSION],
+ m4_defn([_ac_init_VERSION]))])
+m4_ifndef([AC_PACKAGE_STRING],
+ [m4_define([AC_PACKAGE_STRING],
+ m4_defn([_ac_init_NAME])[ ]m4_defn([_ac_init_VERSION]))])
+m4_ifndef([AC_PACKAGE_BUGREPORT],
+ [m4_define([AC_PACKAGE_BUGREPORT], _ac_init_BUGREPORT)])
m4_ifndef([AC_PACKAGE_TARNAME],
[m4_define([AC_PACKAGE_TARNAME],
- m4_default([$4],
- [m4_bpatsubst(m4_tolower(m4_bpatsubst([[$1]],
- [GNU ])),
+ m4_default(m4_defn([_ac_init_TARNAME]),
+ [m4_bpatsubst(m4_tolower(
+ m4_bpatsubst(m4_defn([_ac_init_NAME]),
+ [GNU ])),
[[^_abcdefghijklmnopqrstuvwxyz0123456789]],
[-])]))])
-m4_ifndef([AC_PACKAGE_VERSION],
- [m4_define([AC_PACKAGE_VERSION], [$2])])
-m4_ifndef([AC_PACKAGE_STRING],
- [m4_define([AC_PACKAGE_STRING], [$1 $2])])
-m4_ifndef([AC_PACKAGE_BUGREPORT],
- [m4_define([AC_PACKAGE_BUGREPORT], [$3])])
m4_ifndef([AC_PACKAGE_URL],
[m4_define([AC_PACKAGE_URL],
- m4_if([$5], [], [m4_if(m4_index([$1], [GNU ]), [0],
- [[https://www.gnu.org/software/]m4_defn([AC_PACKAGE_TARNAME])[/]])],
- [[$5]]))])
+ m4_default(m4_defn([_ac_init_URL]),
+ [m4_if(m4_index(m4_defn([_ac_init_NAME]),
+ [GNU ]), [0],
+ [[https://www.gnu.org/software/]m4_defn([AC_PACKAGE_TARNAME])[/]])]))])
+m4_popdef([_ac_init_NAME])
+m4_popdef([_ac_init_VERSION])
+m4_popdef([_ac_init_BUGREPORT])
+m4_popdef([_ac_init_TARNAME])
+m4_popdef([_ac_init_URL])
])
diff --git a/tests/base.at b/tests/base.at
index ff753f1a..98125173 100644
--- a/tests/base.at
+++ b/tests/base.at
@@ -227,7 +227,10 @@ AT_SETUP([AC_INIT with unusual version strings])
AT_DATA([configure.ac],
[[AC_INIT([GNU String++ with spaces (foo)],
- [2.48++ (2010-07-03)], [[https://example.com/?a=b&c=d#e]], [clisp])
+ [2.48++ (2010-07-03)],
+ [[https://example.com/?a=b&c=d#e]],
+ [string++],
+ [[https://example.com/?f=g&h=i%2fj#42]])
AC_OUTPUT
]])
@@ -241,19 +244,20 @@ AT_CHECK_AUTOCONF([-Werror])
AT_CHECK_CONFIGURE([-q])
AT_CHECK_CONFIGURE([--help], [], [stdout])
AT_CHECK([[$FGREP 'com/?a=b&c=d#e' stdout]], [], [ignore])
+AT_CHECK([[$FGREP 'com/?f=g&h=i%2fj#42' stdout]], [], [ignore])
AT_CHECK_CONFIGURE([--version], [], [stdout])
-AT_CHECK([$FGREP 'GNU String++ with spaces (foo)' stdout], [], [ignore])
-AT_CHECK([$FGREP '2.48++ (2010-07-03)' stdout], [], [ignore])
+AT_CHECK([$FGREP 'GNU String++ with spaces (foo)' stdout], [], [ignore])
+AT_CHECK([$FGREP '2.48++ (2010-07-03)' stdout], [], [ignore])
AT_CHECK([./config.status --help], [], [stdout])
AT_CHECK([[$FGREP 'com/?a=b&c=d#e' stdout]], [], [ignore])
AT_CHECK([./config.status --version], [], [stdout])
-AT_CHECK([$FGREP 'GNU String++ with spaces (foo)' stdout], [], [ignore])
-AT_CHECK([$FGREP '2.48++ (2010-07-03)' stdout], [], [ignore])
+AT_CHECK([$FGREP 'GNU String++ with spaces (foo)' stdout], [], [ignore])
+AT_CHECK([$FGREP '2.48++ (2010-07-03)' stdout], [], [ignore])
AT_DATA([configure.ac],
[[AC_INIT([GNU "String++"],
- [2.48], [https://example.com/], [clisp])
+ [2.48], [https://example.com/], [string++])
AC_OUTPUT
]])
@@ -262,7 +266,7 @@ AT_CHECK([grep 'AC_INIT: not a literal: ' stderr], [],
[ignore])
AT_DATA([configure.ac],
[[AC_INIT([GNU String++],
- ['codename' 2.48], [https://example.com/], [clisp])
+ ['codename' 2.48], [https://example.com/], [string++])
AC_OUTPUT
]])
@@ -271,13 +275,66 @@ AT_CHECK([grep 'AC_INIT: not a literal: ' stderr], [],
[ignore])
AT_DATA([configure.ac],
[[AC_INIT([GNU
-String++], [2.48], [https://example.com/], [clisp])
+String++], [2.48], [https://example.com/], [string++])
+AC_OUTPUT
+]])
+
+AT_CHECK_AUTOCONF([-Werror])
+
+AT_DATA([configure.ac],
+[[AC_INIT([GNU String++], ['2.48'], [https://example.com], [string++])
AC_OUTPUT
]])
AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
AT_CHECK([grep 'AC_INIT: not a literal: ' stderr], [], [ignore])
+AT_DATA([configure.ac],
+[[AC_INIT([GNU String++], [2.48], ['https://example.com'], [string++])
+AC_OUTPUT
+]])
+
+AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
+AT_CHECK([grep 'AC_INIT: not a literal: ' stderr], [], [ignore])
+
+AT_DATA([configure.ac],
+[[AC_INIT([GNU String++], [2.48], [https://example.com], [string++],
+ ['https://example.com'])
+AC_OUTPUT
+]])
+
+AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
+AT_CHECK([grep 'AC_INIT: not a literal: ' stderr], [], [ignore])
+
+
+# The TARNAME argument is used to construct filenames, so it's even
+# more constrained.
+
+AT_DATA([configure.ac],
+[[AC_INIT([GNU String++], [2.48], [https://example.com], ['string++'])
+AC_OUTPUT
+]])
+
+AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
+AT_CHECK([grep 'AC_INIT: unsafe as a filename: ' stderr], [], [ignore])
+
+AT_DATA([configure.ac],
+[[AC_INIT([GNU String++], [2.48], [https://example.com], [string ++])
+AC_OUTPUT
+]])
+
+AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
+AT_CHECK([grep 'AC_INIT: unsafe as a filename: ' stderr], [], [ignore])
+
+AT_DATA([configure.ac],
+[[AC_INIT([GNU String++], [2.48], [https://example.com], [string*])
+AC_OUTPUT
+]])
+
+AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
+AT_CHECK([grep 'AC_INIT: unsafe as a filename: ' stderr], [], [ignore])
+
+
AT_CLEANUP
--
2.28.0
- [PATCH 1/2] Trim whitespace from arguments of AC_INIT (#107986),
Zack Weinberg <=