This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GNU M4 source repository".
http://git.sv.gnu.org/gitweb/?p=m4.git;a=commitdiff;h=3e12364a5a32e5947b0c31a2ee6dc5351b7af5e6 The branch, master has been updated via 3e12364a5a32e5947b0c31a2ee6dc5351b7af5e6 (commit) via 5b4325856360a5d8836f13f17938b1acccd422cf (commit) via 185b10ba33786707f6478b8315e9527151f60902 (commit) from 052319b635abea0efba90930031d9c0899dcb0a8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3e12364a5a32e5947b0c31a2ee6dc5351b7af5e6 Author: Eric Blake <[email protected]> Date: Tue Feb 10 14:24:11 2009 -0700 Stage 28c: Warn on embedded NUL in remaining cases. * m4/m4module.h (m4_debug_decode, m4_parse_truth_arg): Add parameter. * m4/macro.c (m4_macro_call): Improve diagnostic. * modules/m4.c (defn): Likewise. * m4/debug.c (m4_debug_decode): Handle embedded NUL. * m4/utility.c (m4_parse_truth_arg): Likewise. * modules/format.c (arg_int, arg_long, arg_double): Likewise. (arg_string): New function. (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE): Update callers. * src/main.c (main): Likewise. * src/freeze.c (reload_frozen_state): Likewise. * modules/gnu.c (debugmode, syncoutput): Likewise. * tests/options.at (--regexp-syntax): Adjust test. * tests/freeze.at (reloading nul): Likewise. * tests/null.m4: Likewise. * tests/null.out: Likewise. * tests/null.err: Likewise. Signed-off-by: Eric Blake <[email protected]> commit 5b4325856360a5d8836f13f17938b1acccd422cf Author: Eric Blake <[email protected]> Date: Sat Feb 7 18:50:21 2009 -0700 Stage 28b: Warn on embedded NUL in file arguments. * m4/path.c (m4_path_search): Quote file names in message. * modules/m4.c (syscmd, include, m4_make_temp): Handle embedded NUL. * modules/gnu.c (debugfile, esyscmd): Likewise. * tests/others.at (nul character): Adjust test. * tests/builtins.at (mkdtemp, mkstemp): Likewise. * tests/null.m4: Likewise. * tests/null.out: Likewise. * tests/null.err: Likewise. Signed-off-by: Eric Blake <[email protected]> commit 185b10ba33786707f6478b8315e9527151f60902 Author: Eric Blake <[email protected]> Date: Thu Feb 5 07:47:32 2009 -0700 Stage 28a: Warn on embedded NUL in numeric arguments. * m4/m4module.h (m4_numeric_arg): Adjust prototype. * m4/utility.c (m4_numeric_arg): Add parameter. * modules/gnu.c (debuglen): Adjust callers. * modules/m4.c (incr, decr, divert, undivert, m4exit, substr) (index): Likewise. * modules/evalparse.c (m4_evaluate): Likewise. * modules/stdlib.c (setenv, getpwuid, srand): Likewise. * modules/time.c (ctime, gmtime, localtime, mktime, strftime): Likewise. * doc/m4.texinfo (Changesyntax): Fix typo. * tests/others.at (nul character): Adjust test. * tests/null.m4: Likewise. * tests/null.out: Likewise. * tests/null.err: Likewise. Signed-off-by: Eric Blake <[email protected]> ----------------------------------------------------------------------- Summary of changes: ChangeLog | 59 +++++++++++++++++++++++++++++++++++++++++++ doc/m4.texinfo | 2 +- m4/debug.c | 29 ++++++++++++++------- m4/m4module.h | 8 +++--- m4/macro.c | 7 +++-- m4/path.c | 7 +++-- m4/utility.c | 39 +++++++++++++++++----------- modules/evalparse.c | 7 +++-- modules/format.c | 61 +++++++++++++++++++++++++++++-------------- modules/gnu.c | 45 +++++++++++++++++++++++--------- modules/m4.c | 70 ++++++++++++++++++++++++++++++++++++-------------- modules/stdlib.c | 13 ++++++--- modules/time.c | 31 +++++++++++++--------- src/freeze.c | 33 +++++++++++++++++++++--- src/main.c | 26 +++++++++++-------- tests/builtins.at | 10 +++--- tests/freeze.at | 14 +++++++++- tests/null.err | Bin 1318 -> 3634 bytes tests/null.m4 | Bin 7559 -> 7702 bytes tests/null.out | Bin 607 -> 632 bytes tests/options.at | 5 ++- tests/others.at | 10 +++++-- 22 files changed, 340 insertions(+), 136 deletions(-) diff --git a/ChangeLog b/ChangeLog index acbdeec..278093f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,64 @@ 2009-02-11 Eric Blake <[email protected]> + Stage 28c: Warn on embedded NUL in remaining cases. + Ensure all remaining warnings can handle embedded NUL. + Memory impact: none. + Speed impact: none noticed. + * m4/m4module.h (m4_debug_decode, m4_parse_truth_arg): Add + parameter. + * m4/macro.c (m4_macro_call): Improve diagnostic. + * modules/m4.c (defn): Likewise. + * m4/debug.c (m4_debug_decode): Handle embedded NUL. + * m4/utility.c (m4_parse_truth_arg): Likewise. + * modules/format.c (arg_int, arg_long, arg_double): Likewise. + (arg_string): New function. + (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE): Update callers. + * src/main.c (main): Likewise. + * src/freeze.c (reload_frozen_state): Likewise. + * modules/gnu.c (debugmode, syncoutput): Likewise. + * tests/options.at (--regexp-syntax): Adjust test. + * tests/freeze.at (reloading nul): Likewise. + * tests/null.m4: Likewise. + * tests/null.out: Likewise. + * tests/null.err: Likewise. + + Stage 28b: Warn on embedded NUL in file arguments. + Quote warning messages related to file and other NUL-terminated + system commands. + Memory impact: none. + Speed impact: none noticed. + * m4/path.c (m4_path_search): Quote file names in message. + * modules/m4.c (syscmd, include, m4_make_temp): Handle embedded + NUL. + * modules/gnu.c (debugfile, esyscmd): Likewise. + * tests/others.at (nul character): Adjust test. + * tests/builtins.at (mkdtemp, mkstemp): Likewise. + * tests/null.m4: Likewise. + * tests/null.out: Likewise. + * tests/null.err: Likewise. + + Stage 28a: Warn on embedded NUL in numeric arguments. + Quote warning messages related to numeric parsing in order to + handle embedded NUL. + Memory impact: none. + Speed impact: none noticed. + * m4/m4module.h (m4_numeric_arg): Adjust prototype. + * m4/utility.c (m4_numeric_arg): Add parameter. + * modules/gnu.c (debuglen): Adjust callers. + * modules/m4.c (incr, decr, divert, undivert, m4exit, substr) + (index): Likewise. + * modules/evalparse.c (m4_evaluate): Likewise. + * modules/stdlib.c (setenv, getpwuid, srand): Likewise. + * modules/time.c (ctime, gmtime, localtime, mktime, strftime): + Likewise. + * doc/m4.texinfo (Changesyntax): Fix typo. + * tests/others.at (nul character): Adjust test. + * tests/null.m4: Likewise. + * tests/null.out: Likewise. + * tests/null.err: Likewise. + +2009-02-11 Eric Blake <[email protected]> + Avoid regression in popdef(undef). * doc/m4.texinfo (Trace): Enhance test, to cover regression recently fixed on the branch. diff --git a/doc/m4.texinfo b/doc/m4.texinfo index f972b48..62fed45 100644 --- a/doc/m4.texinfo +++ b/doc/m4.texinfo @@ -5751,7 +5751,7 @@ parenthesis will match any close parenthesis, etc. @example changesyntax(`(@{<', `)@}>', `,;:', `O(,)') @result{} -e...@{2**4-1; 2 : 8> +e...@{2**4-1; 2: 8> @result{}00001111 @end example diff --git a/m4/debug.c b/m4/debug.c index f5cb4e2..1e1e9a3 100644 --- a/m4/debug.c +++ b/m4/debug.c @@ -1,5 +1,5 @@ /* GNU m4 -- A simple macro processor - Copyright (C) 1991, 1992, 1993, 1994, 2006, 2007, 2008 Free + Copyright (C) 1991, 1992, 1993, 1994, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GNU M4. @@ -30,22 +30,31 @@ static void set_debug_file (m4 *, const m4_call_info *, FILE *); -/* Function to decode the debugging flags OPTS. Used by main while - processing option -d, and by the builtin debugmode (). */ +/* Function to decode the debugging flags OPTS of length LEN; or + SIZE_MAX if OPTS is NUL-terminated. If OPTS is NULL, use the + default flags. Used by main while processing option -d, and by the + builtin debugmode (). */ int -m4_debug_decode (m4 *context, const char *opts) +m4_debug_decode (m4 *context, const char *opts, size_t len) { int previous = context->debug_level; int level; char mode = '\0'; - if (opts == NULL || *opts == '\0') + if (!opts) + opts = ""; + if (len == SIZE_MAX) + len = strlen (opts); + if (!len) level = M4_DEBUG_TRACE_DEFAULT | previous; else { if (*opts == '-' || *opts == '+') - mode = *opts++; - for (level = 0; *opts; opts++) + { + len--; + mode = *opts++; + } + for (level = 0; len--; opts++) { switch (*opts) { @@ -101,9 +110,9 @@ m4_debug_decode (m4 *context, const char *opts) level |= M4_DEBUG_TRACE_DEREF; break; - case 'o': - level |= M4_DEBUG_TRACE_OUTPUT_DUMPDEF; - break; + case 'o': + level |= M4_DEBUG_TRACE_OUTPUT_DUMPDEF; + break; case 'V': level |= M4_DEBUG_TRACE_VERBOSE; diff --git a/m4/m4module.h b/m4/m4module.h index d5ad513..07f8c1a 100644 --- a/m4/m4module.h +++ b/m4/m4module.h @@ -1,6 +1,6 @@ /* GNU m4 -- A simple macro processor Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1999, 2000, 2003, - 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GNU M4. @@ -170,9 +170,9 @@ struct m4_string_pair extern bool m4_bad_argc (m4 *, size_t, const m4_call_info *, size_t, size_t, bool); extern bool m4_numeric_arg (m4 *, const m4_call_info *, const char *, - int *); + size_t, int *); extern bool m4_parse_truth_arg (m4 *, const m4_call_info *, const char *, - bool); + size_t, bool); extern m4_symbol *m4_symbol_value_lookup (m4 *, m4_macro_args *, size_t, bool); /* Error handling. */ @@ -421,7 +421,7 @@ enum { #define m4_is_debug_bit(C,B) ((m4_get_debug_level_opt (C) & (B)) != 0) -extern int m4_debug_decode (m4 *, const char *); +extern int m4_debug_decode (m4 *, const char *, size_t); extern bool m4_debug_set_output (m4 *, const m4_call_info *, const char *); extern void m4_debug_message_prefix (m4 *); diff --git a/m4/macro.c b/m4/macro.c index 7e6ef47..738c8ca 100644 --- a/m4/macro.c +++ b/m4/macro.c @@ -1,6 +1,6 @@ /* GNU m4 -- A simple macro processor Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001, 2006, 2007, - 2008 Free Software Foundation, Inc. + 2008, 2009 Free Software Foundation, Inc. This file is part of GNU M4. @@ -675,8 +675,9 @@ m4_macro_call (m4 *context, m4_symbol_value *value, m4_obstack *expansion, argv); else if (m4_is_symbol_value_placeholder (value)) m4_warn (context, 0, argv->info, - _("builtin `%s' requested by frozen file not found"), - m4_get_symbol_value_placeholder (value)); + _("builtin %s requested by frozen file not found"), + quotearg_style (locale_quoting_style, + m4_get_symbol_value_placeholder (value))); else { assert (!"m4_macro_call"); diff --git a/m4/path.c b/m4/path.c index bf15193..c83aa21 100644 --- a/m4/path.c +++ b/m4/path.c @@ -1,6 +1,6 @@ /* GNU m4 -- A simple macro processor Copyright (C) 1989, 1990, 1991, 1992, 1993, 1998, 2004, 2006, 2007, - 2008 Free Software Foundation, Inc. + 2008, 2009 Free Software Foundation, Inc. This file is part of GNU M4. @@ -198,8 +198,9 @@ m4_path_search (m4 *context, const char *file, char **expanded_name) if (fp != NULL) { m4_debug_message (context, M4_DEBUG_TRACE_PATH, - _("path search for `%s' found `%s'"), - file, name); + _("path search for %s found %s"), + quotearg_style (locale_quoting_style, file), + quotearg_n_style (1, locale_quoting_style, name)); if (expanded_name != NULL) *expanded_name = name; else diff --git a/m4/utility.c b/m4/utility.c index 31c1705..215fabd 100644 --- a/m4/utility.c +++ b/m4/utility.c @@ -1,6 +1,6 @@ /* GNU m4 -- A simple macro processor Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999, 2003, - 2006, 2007, 2008 Free Software Foundation, Inc. + 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GNU M4. @@ -68,43 +68,51 @@ skip_space (m4 *context, const char *arg) return arg; } -/* The function m4_numeric_arg () converts ARG to an int pointed to by - VALUEP. If the conversion fails, print error message for CALLER. - Return true iff conversion succeeds. */ +/* The function m4_numeric_arg () converts ARG of length LEN to an int + pointed to by VALUEP. If the conversion fails, print error message + for CALLER. Return true iff conversion succeeds. */ /* FIXME: Convert this to use gnulib's xstrtoimax, xstrtoumax. Otherwise, we are arbitrarily limiting integer values. */ bool m4_numeric_arg (m4 *context, const m4_call_info *caller, const char *arg, - int *valuep) + size_t len, int *valuep) { char *endp; - if (*arg == '\0') + if (!len) { *valuep = 0; m4_warn (context, 0, caller, _("empty string treated as 0")); } else { - *valuep = strtol (skip_space (context, arg), &endp, 10); - if (*skip_space (context, endp) != 0) + const char *str = skip_space (context, arg); + *valuep = strtol (str, &endp, 10); + if (endp - arg != len) { - m4_warn (context, 0, caller, _("non-numeric argument `%s'"), arg); + m4_warn (context, 0, caller, _("non-numeric argument %s"), + quotearg_style_mem (locale_quoting_style, arg, len)); return false; } + if (str != arg) + m4_warn (context, 0, caller, _("leading whitespace ignored")); + else if (errno == ERANGE) + m4_warn (context, 0, caller, _("numeric overflow detected")); } return true; } -/* Parse ARG as a truth value. If unrecognized, issue a warning on - behalf of CALLER and return PREVIOUS; otherwise return the parsed - value. */ +/* Parse ARG of length LEN as a truth value. If ARG is NUL, use "" + instead; otherwise, ARG must have a NUL-terminator (even if it also + has embedded NUL). If LEN is SIZE_MAX, use the string length of + ARG. If unrecognized, issue a warning on behalf of CALLER and + return PREVIOUS; otherwise return the parsed value. */ bool m4_parse_truth_arg (m4 *context, const m4_call_info *caller, const char *arg, - bool previous) + size_t len, bool previous) { /* 0, no, off, blank... */ - if (!arg || arg[0] == '\0' + if (!arg || len == 0 || arg[0] == '0' || arg[0] == 'n' || arg[0] == 'N' || ((arg[0] == 'o' || arg[0] == 'O') @@ -116,7 +124,8 @@ m4_parse_truth_arg (m4 *context, const m4_call_info *caller, const char *arg, || ((arg[0] == 'o' || arg[0] == 'O') && (arg[1] == 'n' || arg[1] == 'N'))) return true; - m4_warn (context, 0, caller, _("unknown directive `%s'"), arg); + m4_warn (context, 0, caller, _("unknown directive %s"), + quotearg_style_mem (locale_quoting_style, arg, len)); return previous; } diff --git a/modules/evalparse.c b/modules/evalparse.c index ac30cfe..87a318e 100644 --- a/modules/evalparse.c +++ b/modules/evalparse.c @@ -1,6 +1,6 @@ /* GNU m4 -- A simple macro processor Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001, 2006, 2007, - 2008 Free Software Foundation, Inc. + 2008, 2009 Free Software Foundation, Inc. This file is part of GNU M4. @@ -901,7 +901,7 @@ m4_evaluate (m4 *context, m4_obstack *obs, size_t argc, m4_macro_args *argv) eval_error err = NO_ERROR; if (!m4_arg_empty (argv, 2) - && !m4_numeric_arg (context, me, M4ARG (2), &radix)) + && !m4_numeric_arg (context, me, M4ARG (2), M4ARGLEN (2), &radix)) return; if (radix < 1 || radix > 36) @@ -910,7 +910,8 @@ m4_evaluate (m4 *context, m4_obstack *obs, size_t argc, m4_macro_args *argv) return; } - if (argc >= 4 && !m4_numeric_arg (context, me, M4ARG (3), &min)) + if (argc >= 4 && !m4_numeric_arg (context, me, M4ARG (3), M4ARGLEN (3), + &min)) return; if (min < 0) diff --git a/modules/format.c b/modules/format.c index af983cd..55333be 100644 --- a/modules/format.c +++ b/modules/format.c @@ -1,6 +1,6 @@ /* GNU m4 -- A simple macro processor Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001, 2006, 2007, - 2008 Free Software Foundation, Inc. + 2008, 2009 Free Software Foundation, Inc. This file is part of GNU M4. @@ -26,24 +26,27 @@ same size; likewise for long and unsigned long. We do not yet handle long double or long long. */ -/* Parse STR as an integer, reporting warnings on behalf of ME. */ +/* Parse STR of length LEN as an integer, reporting warnings on behalf + of ME. */ static int -arg_int (struct m4 *context, const m4_call_info *me, const char *str) +arg_int (struct m4 *context, const m4_call_info *me, const char *str, + size_t len) { char *endp; long value; /* TODO - also allow parsing `'a' or `"a' which results in the numeric value of 'a', as in printf(1). */ - if (*str == '\0') + if (!len) { m4_warn (context, 0, me, _("empty string treated as 0")); return 0; } errno = 0; value = strtol (str, &endp, 10); - if (*endp != '\0') - m4_warn (context, 0, me, _("non-numeric argument `%s'"), str); + if (endp - str != len) + m4_warn (context, 0, me, _("non-numeric argument %s"), + quotearg_style_mem (locale_quoting_style, str, len)); else if (isspace (to_uchar (*str))) m4_warn (context, 0, me, _("leading whitespace ignored")); else if (errno == ERANGE || (int) value != value) @@ -51,24 +54,27 @@ arg_int (struct m4 *context, const m4_call_info *me, const char *str) return value; } -/* Parse STR as a long, reporting warnings on behalf of ME. */ +/* Parse STR of length LEN as a long, reporting warnings on behalf of + ME. */ static long -arg_long (struct m4 *context, const m4_call_info *me, const char *str) +arg_long (struct m4 *context, const m4_call_info *me, const char *str, + size_t len) { char *endp; long value; /* TODO - also allow parsing `'a' or `"a' which results in the numeric value of 'a', as in printf(1). */ - if (*str == '\0') + if (!len) { m4_warn (context, 0, me, _("empty string treated as 0")); return 0L; } errno = 0; value = strtol (str, &endp, 10); - if (*endp != '\0') - m4_warn (context, 0, me, _("non-numeric argument `%s'"), str); + if (endp - str != len) + m4_warn (context, 0, me, _("non-numeric argument %s"), + quotearg_style_mem (locale_quoting_style, str, len)); else if (isspace (to_uchar (*str))) m4_warn (context, 0, me, _("leading whitespace ignored")); else if (errno == ERANGE) @@ -76,22 +82,37 @@ arg_long (struct m4 *context, const m4_call_info *me, const char *str) return value; } -/* Parse STR as a double, reporting warnings on behalf of ME. */ +/* Check STR of length LEN for embedded NUL, reporting warnings on + behalf of ME. */ +static const char * +arg_string (struct m4 *context, const m4_call_info *me, const char *str, + size_t len) +{ + if (strlen (str) < len) + m4_warn (context, 0, me, _("argument %s truncated"), + quotearg_style_mem (locale_quoting_style, str, len)); + return str; +} + +/* Parse STR of length LEN as a double, reporting warnings on behalf + of ME. */ static double -arg_double (struct m4 *context, const m4_call_info *me, const char *str) +arg_double (struct m4 *context, const m4_call_info *me, const char *str, + size_t len) { char *endp; double value; - if (*str == '\0') + if (!len) { m4_warn (context, 0, me, _("empty string treated as 0")); return 0.0; } errno = 0; value = strtod (str, &endp); - if (*endp != '\0') - m4_warn (context, 0, me, _("non-numeric argument `%s'"), str); + if (endp - str != len) + m4_warn (context, 0, me, _("non-numeric argument %s"), + quotearg_style_mem (locale_quoting_style, str, len)); else if (isspace (to_uchar (*str))) m4_warn (context, 0, me, _("leading whitespace ignored")); else if (errno == ERANGE) @@ -100,16 +121,16 @@ arg_double (struct m4 *context, const m4_call_info *me, const char *str) } #define ARG_INT(i, argc, argv) \ - ((argc <= ++i) ? 0 : arg_int (context, me, M4ARG (i))) + ((argc <= ++i) ? 0 : arg_int (context, me, M4ARG (i), M4ARGLEN (i))) #define ARG_LONG(i, argc, argv) \ - ((argc <= ++i) ? 0L : arg_long (context, me, M4ARG (i))) + ((argc <= ++i) ? 0L : arg_long (context, me, M4ARG (i), M4ARGLEN (i))) #define ARG_STR(i, argc, argv) \ - ((argc <= ++i) ? "" : M4ARG (i)) + ((argc <= ++i) ? "" : arg_string (context, me, M4ARG (i), M4ARGLEN (i))) #define ARG_DOUBLE(i, argc, argv) \ - ((argc <= ++i) ? 0.0 : arg_double (context, me, M4ARG (i))) + ((argc <= ++i) ? 0.0 : arg_double (context, me, M4ARG (i), M4ARGLEN (i))) /* The main formatting function. Output is placed on the obstack OBS, diff --git a/modules/gnu.c b/modules/gnu.c index 8ad1722..f44f0ba 100644 --- a/modules/gnu.c +++ b/modules/gnu.c @@ -1,6 +1,6 @@ /* GNU m4 -- A simple macro processor - Copyright (C) 2000, 2004, 2005, 2006, 2007, 2008 Free Software - Foundation, Inc. + Copyright (C) 2000, 2004, 2005, 2006, 2007, 2008, 2009 Free + Software Foundation, Inc. This file is part of GNU M4. @@ -583,9 +583,17 @@ M4BUILTIN_HANDLER (debugfile) m4_debug_set_output (context, me, NULL); else if (m4_get_safer_opt (context) && !m4_arg_empty (argv, 1)) m4_error (context, 0, 0, me, _("disabled by --safer")); - else if (!m4_debug_set_output (context, me, M4ARG (1))) - m4_error (context, 0, errno, me, _("cannot set debug file %s"), - quotearg_style (locale_quoting_style, M4ARG (1))); + else + { + const char *str = M4ARG (1); + size_t len = M4ARGLEN (1); + if (strlen (str) < len) + m4_warn (context, 0, me, _("argument %s truncated"), + quotearg_style_mem (locale_quoting_style, str, len)); + if (!m4_debug_set_output (context, me, str)) + m4_warn (context, errno, me, _("cannot set debug file %s"), + quotearg_style (locale_quoting_style, str)); + } } @@ -599,7 +607,8 @@ M4BUILTIN_HANDLER (debuglen) { int i; size_t s; - if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), &i)) + if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1), + &i)) return; /* FIXME - make m4_numeric_arg more powerful - we want to accept suffixes, and limit the result to size_t. */ @@ -616,11 +625,14 @@ M4BUILTIN_HANDLER (debuglen) **/ M4BUILTIN_HANDLER (debugmode) { + const char* mode = M4ARG (1); + size_t len = M4ARGLEN (1); if (argc == 1) m4_set_debug_level_opt (context, 0); - else if (m4_debug_decode (context, M4ARG (1)) < 0) - m4_error (context, 0, 0, m4_arg_info (argv), - _("bad debug flags: `%s'"), M4ARG (1)); + else if (m4_debug_decode (context, mode, len) < 0) + m4_warn (context, 0, m4_arg_info (argv), + _("bad debug flags: %s"), + quotearg_style_mem (locale_quoting_style, mode, len)); } @@ -634,6 +646,8 @@ M4BUILTIN_HANDLER (debugmode) M4BUILTIN_HANDLER (esyscmd) { const m4_call_info *me = m4_arg_info (argv); + const char *cmd = M4ARG (1); + size_t len = M4ARGLEN (1); M4_MODULE_IMPORT (m4, m4_set_sysval); M4_MODULE_IMPORT (m4, m4_sysval_flush); @@ -647,9 +661,12 @@ M4BUILTIN_HANDLER (esyscmd) m4_error (context, 0, 0, me, _("disabled by --safer")); return; } + if (strlen (cmd) != len) + m4_warn (context, 0, me, _("argument %s truncated"), + quotearg_style_mem (locale_quoting_style, cmd, len)); /* Optimize the empty command. */ - if (m4_arg_empty (argv, 1)) + if (!*cmd) { m4_set_sysval (0); return; @@ -657,11 +674,12 @@ M4BUILTIN_HANDLER (esyscmd) m4_sysval_flush (context, false); errno = 0; - pin = popen (M4ARG (1), "r"); + pin = popen (cmd, "r"); if (pin == NULL) { m4_error (context, 0, errno, me, - _("cannot open pipe to command `%s'"), M4ARG (1)); + _("cannot open pipe to command %s"), + quotearg_style (locale_quoting_style, cmd)); m4_set_sysval (-1); } else @@ -982,6 +1000,7 @@ M4BUILTIN_HANDLER (m4symbols) M4BUILTIN_HANDLER (syncoutput) { bool value = m4_get_syncoutput_opt (context); - value = m4_parse_truth_arg (context, m4_arg_info (argv), M4ARG (1), value); + value = m4_parse_truth_arg (context, m4_arg_info (argv), M4ARG (1), + M4ARGLEN (1), value); m4_set_syncoutput_opt (context, value); } diff --git a/modules/m4.c b/modules/m4.c index 177590d..1ad1ce1 100644 --- a/modules/m4.c +++ b/modules/m4.c @@ -395,8 +395,10 @@ M4BUILTIN_HANDLER (defn) m4_push_builtin (context, obs, m4_get_symbol_value (symbol)); else if (m4_is_symbol_placeholder (symbol)) m4_warn (context, 0, me, - _("%s: builtin `%s' requested by frozen file not found"), - M4ARG (i), m4_get_symbol_placeholder (symbol)); + _("%s: builtin %s requested by frozen file not found"), + quotearg_n_mem (2, M4ARG (i), M4ARGLEN (i)), + quotearg_style (locale_quoting_style, + m4_get_symbol_placeholder (symbol))); else { assert (!"Bad token data type in m4_defn"); @@ -504,20 +506,27 @@ m4_sysval_flush (m4 *context, bool report) M4BUILTIN_HANDLER (syscmd) { + const m4_call_info *me = m4_arg_info (argv); + const char *cmd = M4ARG (1); + size_t len = M4ARGLEN (1); + if (m4_get_safer_opt (context)) { m4_error (context, 0, 0, m4_arg_info (argv), _("disabled by --safer")); return; } + if (strlen (cmd) != len) + m4_warn (context, 0, me, _("argument %s truncated"), + quotearg_style_mem (locale_quoting_style, cmd, len)); /* Optimize the empty command. */ - if (m4_arg_empty (argv, 1)) + if (!*cmd) { m4_set_sysval (0); return; } m4_sysval_flush (context, false); - m4_sysval = system (M4ARG (1)); + m4_sysval = system (cmd); /* FIXME - determine if libtool works for OS/2, in which case the FUNC_SYSTEM_BROKEN section on the branch must be ported to work around the bug in their EMX libc system(). */ @@ -536,7 +545,8 @@ M4BUILTIN_HANDLER (incr) { int value; - if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), &value)) + if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1), + &value)) return; m4_shipout_int (obs, value + 1); @@ -546,7 +556,8 @@ M4BUILTIN_HANDLER (decr) { int value; - if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), &value)) + if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1), + &value)) return; m4_shipout_int (obs, value - 1); @@ -563,7 +574,7 @@ M4BUILTIN_HANDLER (divert) int i = 0; if (argc >= 2 && !m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), - &i)) + M4ARGLEN (1), &i)) return; m4_make_diversion (context, i); m4_divert_text (context, NULL, M4ARG (2), M4ARGLEN (2), @@ -592,12 +603,17 @@ M4BUILTIN_HANDLER (undivert) for (i = 1; i < argc; i++) { const char *str = M4ARG (i); + size_t len = M4ARGLEN (i); char *endp; int diversion = strtol (str, &endp, 10); - if (*endp == '\0' && !isspace ((unsigned char) *str)) + if (endp - str == len && !isspace ((unsigned char) *str)) m4_insert_diversion (context, diversion); else if (m4_get_posixly_correct_opt (context)) - m4_numeric_arg (context, me, str, &diversion); + m4_warn (context, 0, me, _("non-numeric argument %s"), + quotearg_style_mem (locale_quoting_style, str, len)); + else if (strlen (str) != len) + m4_warn (context, 0, me, _("invalid file name %s"), + quotearg_style_mem (locale_quoting_style, str, len)); else { FILE *fp = m4_path_search (context, str, NULL); @@ -609,7 +625,7 @@ M4BUILTIN_HANDLER (undivert) quotearg_style (locale_quoting_style, str)); } else - m4_error (context, 0, errno, me, _("cannot undivert `%s'"), + m4_error (context, 0, errno, me, _("cannot undivert %s"), quotearg_style (locale_quoting_style, str)); } } @@ -665,13 +681,19 @@ include (m4 *context, int argc, m4_macro_args *argv, bool silent) { FILE *fp; char *name = NULL; + const m4_call_info *me = m4_arg_info (argv); + const char *arg = M4ARG (1); + size_t len = M4ARGLEN (1); - fp = m4_path_search (context, M4ARG (1), &name); + if (strlen (arg) != len) + m4_warn (context, 0, me, _("argument %s truncated"), + quotearg_style_mem (locale_quoting_style, arg, len)); + fp = m4_path_search (context, arg, &name); if (fp == NULL) { if (!silent) m4_error (context, 0, errno, m4_arg_info (argv), _("cannot open %s"), - quotearg_style (locale_quoting_style, M4ARG (1))); + quotearg_style (locale_quoting_style, arg)); return; } @@ -718,6 +740,12 @@ m4_make_temp (m4 *context, m4_obstack *obs, const m4_call_info *caller, successful. */ assert (obstack_object_size (obs) == 0); obstack_grow (obs, quotes->str1, quotes->len1); + if (strlen (pattern) < len) + { + m4_warn (context, 0, caller, _("argument %s truncated"), + quotearg_style_mem (locale_quoting_style, pattern, len)); + len = strlen (pattern); + } obstack_grow (obs, pattern, len); for (i = 0; len > 0 && i < 6; i++) if (pattern[--len] != 'X') @@ -733,10 +761,10 @@ m4_make_temp (m4 *context, m4_obstack *obs, const m4_call_info *caller, /* This use of _() will need to change if xgettext ever changes its undocumented behavior of parsing both string options. */ - m4_error (context, 0, errno, caller, - _(dir ? "cannot create directory from template `%s'" - : "cannot create file from template `%s'"), - pattern); + m4_warn (context, errno, caller, + _(dir ? "cannot create directory from template %s" + : "cannot create file from template %s"), + quotearg_style (locale_quoting_style, pattern)); obstack_free (obs, obstack_finish (obs)); } else @@ -824,7 +852,8 @@ M4BUILTIN_HANDLER (m4exit) int exit_code = EXIT_SUCCESS; /* Warn on bad arguments, but still exit. */ - if (argc >= 2 && !m4_numeric_arg (context, me, M4ARG (1), &exit_code)) + if (argc >= 2 && !m4_numeric_arg (context, me, M4ARG (1), M4ARGLEN (1), + &exit_code)) exit_code = EXIT_FAILURE; if (exit_code < 0 || exit_code > 255) { @@ -919,7 +948,8 @@ M4BUILTIN_HANDLER (index) int retval = -1; if (!m4_arg_empty (argv, 3) && !m4_numeric_arg (context, m4_arg_info (argv), - M4ARG (3), &offset)) + M4ARG (3), M4ARGLEN (3), + &offset)) return; if (offset < 0) { @@ -967,7 +997,7 @@ M4BUILTIN_HANDLER (substr) length = M4ARGLEN (1); if (!m4_arg_empty (argv, 2) - && !m4_numeric_arg (context, me, M4ARG (2), &start)) + && !m4_numeric_arg (context, me, M4ARG (2), M4ARGLEN (2), &start)) return; if (start < 0) start += length; @@ -976,7 +1006,7 @@ M4BUILTIN_HANDLER (substr) end = length; else { - if (!m4_numeric_arg (context, me, M4ARG (3), &end)) + if (!m4_numeric_arg (context, me, M4ARG (3), M4ARGLEN (3), &end)) return; if (end < 0) end += length; diff --git a/modules/stdlib.c b/modules/stdlib.c index b60e977..3fce71f 100644 --- a/modules/stdlib.c +++ b/modules/stdlib.c @@ -1,6 +1,6 @@ /* GNU m4 -- A simple macro processor - Copyright (C) 1999, 2000, 2001, 2006, 2007, 2008 Free Software - Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2006, 2007, 2008, 2009 Free + Software Foundation, Inc. This file is part of GNU M4. @@ -108,7 +108,8 @@ M4BUILTIN_HANDLER (setenv) int overwrite = 1; if (argc >= 4) - if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (3), &overwrite)) + if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (3), M4ARGLEN (3), + &overwrite)) return; #if HAVE_SETENV @@ -206,7 +207,8 @@ M4BUILTIN_HANDLER (getpwuid) struct passwd *pw; int uid; - if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), &uid)) + if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1), + &uid)) return; pw = getpwuid (uid); @@ -261,7 +263,8 @@ M4BUILTIN_HANDLER (srand) seed = time (0L) * getpid (); else { - if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), &seed)) + if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), + M4ARGLEN (1), &seed)) return; } diff --git a/modules/time.c b/modules/time.c index a922a67..ee193a7 100644 --- a/modules/time.c +++ b/modules/time.c @@ -1,6 +1,6 @@ /* GNU m4 -- A simple macro processor - Copyright (C) 1999, 2000, 2001, 2006, 2007, 2008 Free Software - Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2006, 2007, 2008, 2009 Free + Software Foundation, Inc. This file is part of GNU M4. @@ -104,7 +104,8 @@ M4BUILTIN_HANDLER (ctime) if (argc == 2) { - m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), &i); + m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1), + &i); t = i; } else @@ -152,7 +153,8 @@ M4BUILTIN_HANDLER (gmtime) time_t t; int i; - if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), &i)) + if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1), + &i)) return; t = i; @@ -167,7 +169,8 @@ M4BUILTIN_HANDLER (localtime) time_t t; int i; - if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), &i)) + if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1), + &i)) return; t = i; @@ -184,19 +187,20 @@ M4BUILTIN_HANDLER (mktime) struct tm tm; time_t t; - if (!m4_numeric_arg (context, me, M4ARG (1), &tm.tm_sec)) + if (!m4_numeric_arg (context, me, M4ARG (1), M4ARGLEN (1), &tm.tm_sec)) return; - if (!m4_numeric_arg (context, me, M4ARG (2), &tm.tm_min)) + if (!m4_numeric_arg (context, me, M4ARG (2), M4ARGLEN (2), &tm.tm_min)) return; - if (!m4_numeric_arg (context, me, M4ARG (3), &tm.tm_hour)) + if (!m4_numeric_arg (context, me, M4ARG (3), M4ARGLEN (3), &tm.tm_hour)) return; - if (!m4_numeric_arg (context, me, M4ARG (4), &tm.tm_mday)) + if (!m4_numeric_arg (context, me, M4ARG (4), M4ARGLEN (4), &tm.tm_mday)) return; - if (!m4_numeric_arg (context, me, M4ARG (5), &tm.tm_mon)) + if (!m4_numeric_arg (context, me, M4ARG (5), M4ARGLEN (5), &tm.tm_mon)) return; - if (!m4_numeric_arg (context, me, M4ARG (6), &tm.tm_year)) + if (!m4_numeric_arg (context, me, M4ARG (6), M4ARGLEN (6), &tm.tm_year)) return; - if (M4ARG (7) && !m4_numeric_arg (context, me, M4ARG (7), &tm.tm_isdst)) + if (M4ARG (7) && !m4_numeric_arg (context, me, M4ARG (7), M4ARGLEN (7), + &tm.tm_isdst)) return; t = mktime (&tm); @@ -216,7 +220,8 @@ M4BUILTIN_HANDLER (strftime) char *buf; int l; - if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (2), &l)) + if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (2), M4ARGLEN (2), + &l)) return; t = l; diff --git a/src/freeze.c b/src/freeze.c index 0394d4c..1a03842 100644 --- a/src/freeze.c +++ b/src/freeze.c @@ -1,6 +1,6 @@ /* GNU m4 -- A simple macro processor Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2004, 2005, 2006, - 2007, 2008 Free Software Foundation, Inc. + 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GNU M4. @@ -634,7 +634,7 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'd'); GET_STRING (file, string[0], allocated[0], number[0], false); VALIDATE ('\n'); - if (m4_debug_decode (context, string[0]) < 0) + if (m4_debug_decode (context, string[0], number[0]) < 0) m4_error (context, EXIT_FAILURE, 0, NULL, _("unknown debug mode %s"), quotearg_style_mem (locale_quoting_style, string[0], @@ -696,8 +696,21 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'F'); m4_module *module = NULL; m4_symbol_value *token; + // Builtins cannot contain a NUL byte. + if (strlen (string[1]) < number[1]) + m4_error (context, EXIT_FAILURE, 0, NULL, _("\ +ill-formed frozen file, invalid builtin %s encountered"), + quotearg_style_mem (locale_quoting_style, string[1], + number[1])); if (number[2] > 0) - module = m4__module_find (string[2]); + { + if (strlen (string[2]) < number[2]) + m4_error (context, EXIT_FAILURE, 0, NULL, _("\ +ill-formed frozen file, invalid module %s encountered"), + quotearg_style_mem (locale_quoting_style, + string[2], number[2])); + module = m4__module_find (string[2]); + } token = m4_builtin_find_by_name (module, string[1]); if (token == NULL) @@ -732,6 +745,11 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'M'); GET_STRING (file, string[0], allocated[0], number[0], false); VALIDATE ('\n'); + if (strlen (string[0]) < number[0]) + m4_error (context, EXIT_FAILURE, 0, NULL, _("\ +ill-formed frozen file, invalid module %s encountered"), + quotearg_style_mem (locale_quoting_style, + string[0], number[0])); m4__module_open (context, string[0], NULL); break; @@ -940,7 +958,14 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'T'); token = (m4_symbol_value *) xzalloc (sizeof *token); if (number[2] > 0) - module = m4__module_find (string[2]); + { + if (strlen (string[2]) < number[2]) + m4_error (context, EXIT_FAILURE, 0, NULL, _("\ +ill-formed frozen file, invalid module %s encountered"), + quotearg_style_mem (locale_quoting_style, + string[2], number[2])); + module = m4__module_find (string[2]); + } m4_set_symbol_value_text (token, xmemdup0 (string[1], number[1]), number[1], 0); diff --git a/src/main.c b/src/main.c index b4d8da8..c2e19bd 100644 --- a/src/main.c +++ b/src/main.c @@ -459,7 +459,7 @@ main (int argc, char *const *argv, char *const *envp) break; case 'E': - m4_debug_decode (context, "-d"); + m4_debug_decode (context, "-d", SIZE_MAX); if (m4_get_fatal_warnings_opt (context)) m4_set_warnings_exit_opt (context, true); else @@ -491,12 +491,13 @@ main (int argc, char *const *argv, char *const *envp) const char *dlerr = lt_dlerror (); if (dlerr == NULL) m4_error (context, EXIT_FAILURE, 0, NULL, - _("failed to add search directory `%s'"), - optarg); + _("failed to add search directory %s"), + quotearg_style (locale_quoting_style, optarg)); else m4_error (context, EXIT_FAILURE, 0, NULL, - _("failed to add search directory `%s': %s"), - optarg, dlerr); + _("failed to add search directory %s: %s"), + quotearg_style (locale_quoting_style, optarg), + dlerr); } break; @@ -533,8 +534,9 @@ main (int argc, char *const *argv, char *const *envp) have effect between files. */ if (seen_file || frozen_file_to_read) goto defer; - if (m4_debug_decode (context, optarg) < 0) - error (0, 0, _("bad debug flags: `%s'"), optarg); + if (m4_debug_decode (context, optarg, SIZE_MAX) < 0) + error (0, 0, _("bad debug flags: %s"), + quotearg_style (locale_quoting_style, optarg)); break; case 'e': @@ -689,8 +691,9 @@ main (int argc, char *const *argv, char *const *envp) break; case 'd': - if (m4_debug_decode (context, arg) < 0) - error (0, 0, _("bad debug flags: `%s'"), arg); + if (m4_debug_decode (context, arg, SIZE_MAX) < 0) + error (0, 0, _("bad debug flags: %s"), + quotearg_style (locale_quoting_style, arg)); break; case 'm': @@ -702,7 +705,8 @@ main (int argc, char *const *argv, char *const *envp) m4_set_regexp_syntax_opt (context, m4_regexp_syntax_encode (arg)); if (m4_get_regexp_syntax_opt (context) < 0) m4_error (context, EXIT_FAILURE, 0, NULL, - _("bad regexp syntax option: `%s'"), arg); + _("bad syntax-spec: %s"), + quotearg_style (locale_quoting_style, arg)); break; case 't': @@ -736,7 +740,7 @@ main (int argc, char *const *argv, char *const *envp) info.name_len = strlen (info.name); m4_set_syncoutput_opt (context, m4_parse_truth_arg (context, &info, arg, - previous)); + SIZE_MAX, previous)); } break; diff --git a/tests/builtins.at b/tests/builtins.at index f819403..397f649 100644 --- a/tests/builtins.at +++ b/tests/builtins.at @@ -1,5 +1,5 @@ # Hand crafted tests for GNU M4. -*- Autotest -*- -# Copyright (C) 2001, 2006, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2001, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is part of GNU M4. # @@ -713,8 +713,8 @@ dnl Check that on error, the expansion is void AT_DATA([[in]], [[mkdtemp(`no_such_dir/m4-fooXXXXXX') ]]) -AT_CHECK_M4([in], [1], [[ -]], [[m4:in:1: mkdtemp: cannot create directory from template `no_such_dir/m4-fooXXXXXX': No such file or directory +AT_CHECK_M4([in], [0], [[ +]], [[m4:in:1: Warning: mkdtemp: cannot create directory from template `no_such_dir/m4-fooXXXXXX': No such file or directory ]]) dnl Check that umask has an effect. drws--S--T is okay. @@ -742,8 +742,8 @@ dnl Check that on error, the expansion is void AT_DATA([[in]], [[mkstemp(`no_such_dir/m4-fooXXXXXX') ]]) -AT_CHECK_M4([in], [1], [[ -]], [[m4:in:1: mkstemp: cannot create file from template `no_such_dir/m4-fooXXXXXX': No such file or directory +AT_CHECK_M4([in], [0], [[ +]], [[m4:in:1: Warning: mkstemp: cannot create file from template `no_such_dir/m4-fooXXXXXX': No such file or directory ]]) dnl Check that extra X are appended, but not trailing NUL diff --git a/tests/freeze.at b/tests/freeze.at index 693ae54..338f6f5 100644 --- a/tests/freeze.at +++ b/tests/freeze.at @@ -1,5 +1,5 @@ # Hand crafted tests for GNU M4. -*- Autotest -*- -# Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is part of GNU M4. # @@ -415,6 +415,18 @@ AT_CHECK_M4([-R bogus.m4f], [1], [], [[m4:bogus.m4f:4: bad syntax-spec `gnu\0' ]]) +dnl Reject escape sequences that expand to unexpected NUL +AT_DATA([bogus.m4f], +[[# bogus frozen file +V2 +F3,4 +len +len\0 +]]) +AT_CHECK_M4([-R bogus.m4f], [1], [], +[[m4:bogus.m4f:5: ill-formed frozen file, invalid builtin `len\0' encountered +]]) + AT_CLEANUP ]) diff --git a/tests/null.err b/tests/null.err index 7b9f798..38c610f 100644 Binary files a/tests/null.err and b/tests/null.err differ diff --git a/tests/null.m4 b/tests/null.m4 index f7a1587..0e13cb4 100644 Binary files a/tests/null.m4 and b/tests/null.m4 differ diff --git a/tests/null.out b/tests/null.out index 97f80dd..993d9fe 100644 Binary files a/tests/null.out and b/tests/null.out differ diff --git a/tests/options.at b/tests/options.at index 48e5b03..ad71f20 100644 --- a/tests/options.at +++ b/tests/options.at @@ -1,5 +1,6 @@ # Hand crafted tests for GNU M4. -*- Autotest -*- -# Copyright (C) 2001, 2006, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2001, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # This file is part of GNU M4. # @@ -722,7 +723,7 @@ AT_DATA([[in]], [[regexp(`(', `(') ]]) AT_CHECK_M4([--regexp-syntax=unknown in], [1], [], -[[m4: bad regexp syntax option: `unknown' +[[m4: bad syntax-spec: `unknown' ]]) AT_CHECK_M4([--regexp-syntax= in], [0], [[0 diff --git a/tests/others.at b/tests/others.at index 6776ee3..779fd3c 100644 --- a/tests/others.at +++ b/tests/others.at @@ -1,5 +1,6 @@ # Hand crafted tests for GNU M4. -*- Autotest -*- -# Copyright (C) 2001, 2006, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2001, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # This file is part of GNU M4. # @@ -429,11 +430,14 @@ $SED "s|null.m4|$abs_srcdir/null.m4|" < "$abs_srcdir/null.out" > expout $SED "s|null.m4|$abs_srcdir/null.m4|" < "$abs_srcdir/null.err" > experr dnl all but m4exit -AT_CHECK_M4([-Dm4exit -I "$abs_srcdir" null.m4], [0], [expout], [experr]) +AT_CHECK_M4([-Dm4exit -I "$abs_srcdir" null.m4], [1], [expout], [experr]) dnl just m4exit -AT_CHECK_M4(["$abs_srcdir/null.m4"], [2], +AT_CHECK_M4(["$abs_srcdir/null.m4"], [1], [[# This file tests m4 behavior on NUL bytes. +]], [stderr]) +AT_CHECK([sed "s|$abs_srcdir/||" stderr], [0], +[[m4:null.m4:5: Warning: m4exit: non-numeric argument `2\0002' ]]) AT_CLEANUP hooks/post-receive -- GNU M4 source repository
