-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 According to Eric Blake on 11/10/2008 7:53 PM: > I downgraded, and I can reproduce a different crash on cygwin, so it looks > like we're now tickling a m4 memory corruption bug: > > Meanwhile, m4 1.4.11 passed. I'm in the middle of bisecting which > autoconf patch tickled the bug, and which m4 release fixed it.
Found it. The NEWS for m4 1.4.9b states: * The `format' builtin now understands formats such as %a, %A, and %'hhd, and works around a number of platform printf bugs. Furthermore, the sequence format(%*.*d,-1,-1,1) no longer outputs random data. And sure enough: $ m4-1.4.9/src/m4 format("%.1s",abc) "a" format("%.*s",-1,abc) "(L"" format("%.*s",-2,abc) "abc" format("%.*s",1,abc) "a" $ ../m4-1.4.9b/src/m4 format("%.1s",abc) "a" format("%.*s",-1,abc) "abc" format("%.*s",-2,abc) "abc" format("%.*s",1,abc) "a" I'm not yet ready to require m4 1.4.10 (1.4.5 is still not even 3 years old), so the correct solution is to avoid tickling the bug. Since the bug is only present when using exactly -1 as a precision argument; any other value works. Meanwhile, I didn't want to penalize newer m4 with the extra m4_eval, hence I created a new m4sugar macro _m4_index, and make it directly use the builtin on newer m4. I'm committing this, tested across a number of versions spanning from m4 1.4.5 through m4.git. It also fixes an accidental regression in the final hunk of http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=2922868#patch7, - -- Don't work too hard, make some time for fun as well! Eric Blake [EMAIL PROTECTED] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkkZBNUACgkQ84KuGfSFAYBIIwCdGHk7R1kEStxZxhw454BoPMBL svIAnRt6jOOJPLSNir0mGiBVKloFWJhJ =y3iB -----END PGP SIGNATURE-----
>From 74bb1a450dd690f08cd39a6597f2acbb76c69024 Mon Sep 17 00:00:00 2001 From: Eric Blake <[EMAIL PROTECTED]> Date: Mon, 10 Nov 2008 21:00:44 -0700 Subject: [PATCH] Work around <=m4-1.4.9 bug in m4_format. * lib/m4sugar/m4sugar.m4 (_m4_index): New internal macro. (m4_init): Only use it in older m4. * lib/autoconf/general.m4 (_AC_DEFINE_Q): Use it to avoid m4_format bug in older m4. * lib/autoconf/status.m4 (_AC_CONFIG_COMPUTE_DEST): Likewise. Reported by Bob Proulx. Signed-off-by: Eric Blake <[EMAIL PROTECTED]> --- ChangeLog | 10 ++++++++++ lib/autoconf/general.m4 | 4 +++- lib/autoconf/status.m4 | 4 ++-- lib/m4sugar/m4sugar.m4 | 26 ++++++++++++++++++++++---- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2367c7c..b28abcd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2008-11-10 Eric Blake <[EMAIL PROTECTED]> + Work around <=m4-1.4.9 bug in m4_format. + * lib/m4sugar/m4sugar.m4 (_m4_index): New internal macro. + (m4_init): Only use it in older m4. + * lib/autoconf/general.m4 (_AC_DEFINE_Q): Use it to avoid + m4_format bug in older m4. + * lib/autoconf/status.m4 (_AC_CONFIG_COMPUTE_DEST): Likewise. + Reported by Bob Proulx. + +2008-11-10 Eric Blake <[EMAIL PROTECTED]> + Match upstream standards.texi. * doc/standards.texi: Resync from upstream. * doc/fdl-1.3.texi: Rename... diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4 index 2c184fc..15377cb 100644 --- a/lib/autoconf/general.m4 +++ b/lib/autoconf/general.m4 @@ -2077,8 +2077,10 @@ m4_define([AC_DEFINE_UNQUOTED], [_AC_DEFINE_Q([], $@)]) # m4_format rather than regex to grab prefix up to first (). AC_name # is defined with over-quotation, so that we can avoid m4_defn; this # is only safe because the name should not contain $. +# +# Use _m4_index to avoid a bug in m4_format in older m4. m4_define([_AC_DEFINE_Q], -[m4_pushdef([AC_name], m4_format([[[%.*s]]], m4_index([$2], [(]), [$2]))]dnl +[m4_pushdef([AC_name], m4_format([[[%.*s]]], _m4_index([$2], [(]), [$2]))]dnl [AC_DEFINE_TRACE(AC_name)]dnl [m4_cond([m4_index([$3], [ ])], [-1], [], diff --git a/lib/autoconf/status.m4 b/lib/autoconf/status.m4 index 388b90f..c134bb7 100644 --- a/lib/autoconf/status.m4 +++ b/lib/autoconf/status.m4 @@ -247,9 +247,9 @@ m4_define([_AC_CONFIG_FOOS], # _AC_CONFIG_COMPUTE_DEST(STRING) # ------------------------------- # Compute the DEST from STRING by stripping any : and following -# characters. +# characters. Use _m4_index to avoid a bug in m4_format in older m4. m4_define([_AC_CONFIG_COMPUTE_DEST], -[m4_format([[%.*s]], m4_index([$1], [:]), [$1])]) +[m4_format([[%.*s]], _m4_index([$1], [:]), [$1])]) # _AC_CONFIG_REGISTER(MODE, TAG, [COMMANDS]) # ------------------------------------------ diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4 index 2a0d7ce..8884714 100644 --- a/lib/m4sugar/m4sugar.m4 +++ b/lib/m4sugar/m4sugar.m4 @@ -625,6 +625,22 @@ m4_define([m4_dumpdefs], [m4_map_args([$0], $@)])]) +# _m4_index(HAYSTACK, NEEDLE) +# --------------------------- +# Like the original, except return -2 instead of -1 if NEEDLE is not +# present in HAYSTACK. That way, it can be used to work around a bug +# in m4 1.4.9 and earlier where m4_format did not accept a precision +# of -1; this macro can be safely used in the idiom: +# m4_format([[%.*s]], _m4_index([$1],[$2]), [$1]) +# to grab the prefix of $1 up to but excluding $2, if it was present, +# otherwise the entire $1. +m4_define([_m4_index], +[$0_(m4_index($@))]) + +m4_define([_m4_index_], +[m4_if([$1], [-1], [-2], [$1])]) + + # m4_popdef(NAME) # --------------- # Like the original, except guarantee a warning when using something which is @@ -2975,7 +2991,8 @@ m4_pattern_forbid([^dnl$]) # If __m4_version__ is defined, we assume that we are being run by M4 # 1.6 or newer, and thus that $@ recursion is linear and debugmode(d) -# is available for faster checks of dereferencing undefined macros. +# is available for faster checks of dereferencing undefined macros, +# and we don't need to worry about _m4_format bugs with _m4_index. # But if it is missing, we assume we are being run by M4 1.4.x, that # $@ recursion is quadratic, and that we need foreach-based # replacement macros. Use the raw builtin to avoid tripping up @@ -2983,9 +3000,10 @@ m4_pattern_forbid([^dnl$]) # undefines m4_defn. m4_ifdef([__m4_version__], [m4_debugmode([+d]) -m4_define([m4_defn], _m4_defn([m4_defn])) -m4_define([m4_popdef], _m4_defn([m4_popdef])) -m4_define([m4_undefine], _m4_defn([m4_undefine]))], +m4_define([m4_defn], _m4_defn([_m4_defn])) +m4_define([_m4_index], _m4_defn([m4_index])) +m4_define([m4_popdef], _m4_defn([_m4_popdef])) +m4_define([m4_undefine], _m4_defn([_m4_undefine]))], [m4_builtin([include], [m4sugar/foreach.m4])]) # Rewrite the first entry of the diversion stack. -- 1.6.0.2