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=1b5e6019b86abfc086af32b79087b8e862ed7a81 The branch, branch-1.6 has been updated via 1b5e6019b86abfc086af32b79087b8e862ed7a81 (commit) from f35224878771517f1d7c13568c1b65a59e7908a4 (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 1b5e6019b86abfc086af32b79087b8e862ed7a81 Author: Eric Blake <[email protected]> Date: Tue Feb 5 11:41:05 2008 -0700 Stage 28: Allow embedded NUL in warning messages. * src/m4.h (debug_decode): Add argument. * src/m4.c (main): Adjust caller. * src/format.c (arg_int, arg_long, arg_double): Likewise. (arg_string): New function. (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE): Support embedded NUL. * src/freeze.c (reload_frozen_state): Likewise. * src/debug.c (debug_decode): Likewise. * src/builtin.c (numeric_arg): Add argument. (m4_syscmd, m4_esyscmd, m4_eval, m4_incr, m4_decr, m4_divert) (m4_undivert, include, mkstemp_helper, m4_m4exit, m4_debugmode) (m4_debugfile, m4_index, m4_substr): Detect embedded NUL. (m4_defn, m4_maketemp, m4_placeholder): Improve warning message. * src/path.c (m4_path_search): Likewise. * doc/m4.texinfo (Syntax, Mkstemp, Using frozen files): Adjust tests. * examples/null.m4: Likewise. * examples/null.out: Likewise. * examples/null.err: Likewise. Signed-off-by: Eric Blake <[email protected]> (cherry picked from commit fd9f6463352aee342c4061b5df9d0f4bf56742c7) ----------------------------------------------------------------------- Summary of changes: ChangeLog | 28 ++++++++++++ doc/m4.texinfo | 20 ++++++++- examples/null.err | Bin 1078 -> 3298 bytes examples/null.m4 | Bin 6667 -> 6776 bytes examples/null.out | Bin 553 -> 578 bytes src/builtin.c | 121 ++++++++++++++++++++++++++++++++++++----------------- src/debug.c | 30 ++++++++----- src/format.c | 55 ++++++++++++++++-------- src/freeze.c | 13 ++++-- src/m4.c | 14 ++++--- src/m4.h | 2 +- src/path.c | 10 +++- 12 files changed, 210 insertions(+), 83 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2aa09b4..39d40df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,33 @@ 2009-02-11 Eric Blake <[email protected]> + Stage 28: Allow embedded NUL in warning messages. + Issue graceful error messages for a variety of places where + embedded NUL is otherwise unhandled. For example, numeric parsing + rejects embedded NUL, while file-related commands warn about + truncation at NUL, and frozen files detect unexpected NUL. + Memory impact: none. + Speed impact: none noticed. + * src/m4.h (debug_decode): Add argument. + * src/m4.c (main): Adjust caller. + * src/format.c (arg_int, arg_long, arg_double): Likewise. + (arg_string): New function. + (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE): Support embedded NUL. + * src/freeze.c (reload_frozen_state): Likewise. + * src/debug.c (debug_decode): Likewise. + * src/builtin.c (numeric_arg): Add argument. + (m4_syscmd, m4_esyscmd, m4_eval, m4_incr, m4_decr, m4_divert) + (m4_undivert, include, mkstemp_helper, m4_m4exit, m4_debugmode) + (m4_debugfile, m4_index, m4_substr): Detect embedded NUL. + (m4_defn, m4_maketemp, m4_placeholder): Improve warning message. + * src/path.c (m4_path_search): Likewise. + * doc/m4.texinfo (Syntax, Mkstemp, Using frozen files): Adjust + tests. + * examples/null.m4: Likewise. + * examples/null.out: Likewise. + * examples/null.err: Likewise. + +2009-02-11 Eric Blake <[email protected]> + Warn when popping traced but undefined macro. * src/symtab.c (lookup_symbol): Recognize traced placeholder when delete is requested. Bug introduced 2008-07-18. diff --git a/doc/m4.texinfo b/doc/m4.texinfo index b337e5e..fd48e80 100644 --- a/doc/m4.texinfo +++ b/doc/m4.texinfo @@ -1081,14 +1081,16 @@ exception of the @sc{nul} character (the zero byte @samp{'\0'}). @comment xout: null.out @comment xerr: null.err +...@comment status: 1 @example define(`m4exit')include(`null.m4')dnl @end example -...@comment status: 2 +...@comment status: 1 @example include(`null.m4') @result{}# This file tests m4 behavior on NUL bytes. +...@error{}m4:examples/null.m4:5: Warning: m4exit: non-numeric argument `2\0002' @end example @end ignore @@ -7485,10 +7487,12 @@ define(`foo', `errprint(`oops')') syscmd(`rm -f foo-??????')sysval @result{}0 define(`file1', maketemp(`foo-XXXXXX'))dnl +...@error{}m4:stdin:3: Warning: maketemp: recommend using mkstemp instead ifelse(esyscmd(`echo \` foo-?????? \''), ` foo-?????? ', `no file', `created') @result{}created define(`file2', maketemp(`foo-XX'))dnl +...@error{}m4:stdin:6: Warning: maketemp: recommend using mkstemp instead define(`file3', mkstemp(`foo-XXXXXX'))dnl ifelse(len(defn(`file1')), len(defn(`file2')), `same length', `different') @@ -7905,6 +7909,20 @@ divert(1)undivert(null.out)' | ]__program__[ -F in.m4f \ ])dnl @error{}divnum #-- 3 0 @end example + +...@c Do we reject unexpected NUL bytes? + +...@example +ifdef(`__unix__', , + `errprint(` skipping: syscmd does not have unix semantics +')m4exit(`77')')dnl +changequote(`[', `]')dnl +syscmd([printf '#bogus\nV1\nF3,4\nlenlen\0\n' > in.m4f \ + && ]__program__[ -R in.m4f \ + && rm in.m4f])sysval +...@error{}m4:in.m4f:4: ill-formed frozen file, invalid builtin `len\0' encountered +...@result{}1 +...@end example @end ignore When an @code{m4} run is to be frozen, the automatic undiversion diff --git a/examples/null.err b/examples/null.err index 977b3b7..8446d78 100644 Binary files a/examples/null.err and b/examples/null.err differ diff --git a/examples/null.m4 b/examples/null.m4 index e60aec5..3f901f4 100644 Binary files a/examples/null.m4 and b/examples/null.m4 differ diff --git a/examples/null.out b/examples/null.out index c2c1cb9..812df0c 100644 Binary files a/examples/null.out and b/examples/null.out differ diff --git a/src/builtin.c b/src/builtin.c index a398fdb..22d156d 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -564,18 +564,18 @@ bad_argc (const call_info *name, int argc, unsigned int min, unsigned int max) return false; } -/*-------------------------------------------------------------------. -| The function numeric_arg () converts ARG to an int pointed to by | -| VALUEP. If the conversion fails, print error message on behalf of | -| NAME. Return true iff conversion succeeds. | -`-------------------------------------------------------------------*/ +/*------------------------------------------------------------------. +| The function numeric_arg () converts ARG of length LEN to an int | +| pointed to by VALUEP. If the conversion fails, print error | +| message on behalf of NAME. Return true iff conversion succeeds. | +`------------------------------------------------------------------*/ static bool -numeric_arg (const call_info *name, const char *arg, int *valuep) +numeric_arg (const call_info *name, const char *arg, size_t len, int *valuep) { char *endp; - if (*arg == '\0') + if (!len) { *valuep = 0; m4_warn (0, name, _("empty string treated as 0")); @@ -584,9 +584,10 @@ numeric_arg (const call_info *name, const char *arg, int *valuep) { errno = 0; *valuep = strtol (arg, &endp, 10); - if (*endp != '\0') + if (endp - arg != len) { - m4_warn (0, name, _("non-numeric argument `%s'"), arg); + m4_warn (0, name, _("non-numeric argument %s"), + quotearg_style_mem (locale_quoting_style, arg, len)); return false; } if (isspace (to_uchar (*arg))) @@ -1087,8 +1088,9 @@ m4_defn (struct obstack *obs, int argc, macro_arguments *argv) b = SYMBOL_FUNC (s); if (b == m4_placeholder) m4_warn (0, me, - _("builtin `%s' requested by frozen file not found"), - ARG (i)); + _("builtin %s requested by frozen file not found"), + quotearg_style_mem (locale_quoting_style, ARG (i), + ARG_LEN (i))); else push_macro (obs, b); break; @@ -1140,7 +1142,14 @@ static int sysval; static void m4_syscmd (struct obstack *obs, int argc, macro_arguments *argv) { - if (bad_argc (arg_info (argv), argc, 1, 1)) + const call_info *me = arg_info (argv); + const char *cmd = ARG (1); + size_t len = ARG_LEN (1); + + if (strlen (cmd) != len) + m4_warn (0, me, _("argument %s truncated"), + quotearg_style_mem (locale_quoting_style, cmd, len)); + if (bad_argc (me, argc, 1, 1) || !*cmd) { /* The empty command is successful. */ sysval = 0; @@ -1148,7 +1157,7 @@ m4_syscmd (struct obstack *obs, int argc, macro_arguments *argv) } debug_flush_files (); - sysval = system (ARG (1)); + sysval = system (cmd); #if FUNC_SYSTEM_BROKEN /* OS/2 has a buggy system() that returns exit status in the lowest eight bits, although pclose() and WEXITSTATUS are defined to return exit @@ -1165,10 +1174,15 @@ static void m4_esyscmd (struct obstack *obs, int argc, macro_arguments *argv) { const call_info *me = arg_info (argv); + const char *cmd = ARG (1); + size_t len = ARG_LEN (1); FILE *pin; int ch; - if (bad_argc (me, argc, 1, 1)) + if (strlen (cmd) != len) + m4_warn (0, me, _("argument %s truncated"), + quotearg_style_mem (locale_quoting_style, cmd, len)); + if (bad_argc (me, argc, 1, 1) || !*cmd) { /* The empty command is successful. */ sysval = 0; @@ -1177,10 +1191,11 @@ m4_esyscmd (struct obstack *obs, int argc, macro_arguments *argv) debug_flush_files (); errno = 0; - pin = popen (ARG (1), "r"); + pin = popen (cmd, "r"); if (pin == NULL) { - m4_warn (errno, me, _("cannot open pipe to command `%s'"), ARG (1)); + m4_warn (errno, me, _("cannot open pipe to command %s"), + quotearg_style (locale_quoting_style, cmd)); sysval = -1; } else @@ -1217,7 +1232,7 @@ m4_eval (struct obstack *obs, int argc, macro_arguments *argv) if (bad_argc (me, argc, 1, 3)) return; - if (!arg_empty (argv, 2) && !numeric_arg (me, ARG (2), &radix)) + if (!arg_empty (argv, 2) && !numeric_arg (me, ARG (2), ARG_LEN (2), &radix)) return; if (radix < 1 || radix > 36) @@ -1226,7 +1241,7 @@ m4_eval (struct obstack *obs, int argc, macro_arguments *argv) return; } - if (argc >= 4 && !numeric_arg (me, ARG (3), &min)) + if (argc >= 4 && !numeric_arg (me, ARG (3), ARG_LEN (3), &min)) return; if (min < 0) { @@ -1281,7 +1296,7 @@ m4_incr (struct obstack *obs, int argc, macro_arguments *argv) if (bad_argc (me, argc, 1, 1)) return; - if (!numeric_arg (me, ARG (1), &value)) + if (!numeric_arg (me, ARG (1), ARG_LEN (1), &value)) return; shipout_int (obs, value + 1); @@ -1296,7 +1311,7 @@ m4_decr (struct obstack *obs, int argc, macro_arguments *argv) if (bad_argc (me, argc, 1, 1)) return; - if (!numeric_arg (me, ARG (1), &value)) + if (!numeric_arg (me, ARG (1), ARG_LEN (1), &value)) return; shipout_int (obs, value - 1); @@ -1317,7 +1332,7 @@ m4_divert (struct obstack *obs, int argc, macro_arguments *argv) int i = 0; bad_argc (me, argc, 0, 2); - if (argc >= 2 && !numeric_arg (me, ARG (1), &i)) + if (argc >= 2 && !numeric_arg (me, ARG (1), ARG_LEN (1), &i)) return; make_diversion (i); @@ -1357,11 +1372,16 @@ m4_undivert (struct obstack *obs, int argc, macro_arguments *argv) for (i = 1; i < argc; i++) { const char *str = ARG (i); + size_t len = ARG_LEN (i); file = strtol (str, &endp, 10); - if (*endp == '\0' && !isspace (to_uchar (*str))) + if (endp - str == len && !isspace (to_uchar (*str))) insert_diversion (file); else if (no_gnu_extensions) - m4_warn (0, me, _("non-numeric argument `%s'"), str); + m4_warn (0, me, _("non-numeric argument %s"), + quotearg_style_mem (locale_quoting_style, str, len)); + else if (strlen (str) != len) + m4_warn (0, me, _("invalid file name %s"), + quotearg_style_mem (locale_quoting_style, str, len)); else { fp = m4_path_search (str, NULL); @@ -1473,16 +1493,23 @@ include (int argc, macro_arguments *argv, bool silent) const call_info *me = arg_info (argv); FILE *fp; char *name; + const char *arg; + size_t len; if (bad_argc (me, argc, 1, 1)) return; - fp = m4_path_search (ARG (1), &name); + arg = ARG (1); + len = ARG_LEN (1); + if (strlen (arg) != len) + m4_warn (0, me, _("argument %s truncated"), + quotearg_style_mem (locale_quoting_style, arg, len)); + fp = m4_path_search (arg, &name); if (fp == NULL) { if (!silent) m4_error (0, errno, me, _("cannot open %s"), - quotearg_style (locale_quoting_style, ARG (1))); + quotearg_style (locale_quoting_style, arg)); return; } @@ -1532,6 +1559,12 @@ mkstemp_helper (struct obstack *obs, const call_info *me, const char *pattern, user forgot to supply them. Output must be quoted if successful. */ obstack_grow (obs, curr_quote.str1, curr_quote.len1); + if (strlen (pattern) < len) + { + m4_warn (0, me, _("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') @@ -1543,7 +1576,8 @@ mkstemp_helper (struct obstack *obs, const call_info *me, const char *pattern, fd = mkstemp (name); if (fd < 0) { - m4_warn (errno, me, _("cannot create tempfile `%s'"), pattern); + m4_warn (errno, me, _("cannot create file from template %s"), + quotearg_style (locale_quoting_style, pattern)); obstack_free (obs, obstack_finish (obs)); } else @@ -1562,6 +1596,7 @@ m4_maketemp (struct obstack *obs, int argc, macro_arguments *argv) if (bad_argc (me, argc, 1, 1)) return; + m4_warn (0, me, _("recommend using mkstemp instead")); if (no_gnu_extensions) { /* POSIX states "any trailing 'X' characters [are] replaced with @@ -1583,7 +1618,6 @@ m4_maketemp (struct obstack *obs, int argc, macro_arguments *argv) (unsigned long) getpid ()); char *pid = (char *) obstack_copy0 (scratch, "", 0); - m4_warn (0, me, _("recommend using mkstemp instead")); for (i = len; i > 1; i--) if (str[i - 1] != 'X') break; @@ -1669,7 +1703,7 @@ m4_m4exit (struct obstack *obs, int argc, macro_arguments *argv) /* Warn on bad arguments, but still exit. */ bad_argc (me, argc, 0, 1); - if (argc >= 2 && !numeric_arg (me, ARG (1), &exit_code)) + if (argc >= 2 && !numeric_arg (me, ARG (1), ARG_LEN (1), &exit_code)) exit_code = EXIT_FAILURE; if (exit_code < 0 || exit_code > 255) { @@ -1784,13 +1818,15 @@ m4_debugmode (struct obstack *obs, int argc, macro_arguments *argv) { const call_info *me = arg_info (argv); const char *str = ARG (1); + size_t len = ARG_LEN (1); bad_argc (me, argc, 0, 1); if (argc == 1) debug_level = 0; - else if (debug_decode (str) < 0) - m4_warn (0, me, _("bad debug flags: `%s'"), str); + else if (debug_decode (str, len) < 0) + m4_warn (0, me, _("bad debug flags: %s"), + quotearg_style_mem (locale_quoting_style, str, len)); } /*-------------------------------------------------------------------------. @@ -1807,9 +1843,17 @@ m4_debugfile (struct obstack *obs, int argc, macro_arguments *argv) if (argc == 1) debug_set_output (me, NULL); - else if (!debug_set_output (me, ARG (1))) - m4_warn (errno, me, _("cannot set debug file %s"), - quotearg_style (locale_quoting_style, ARG (1))); + else + { + const char *str = ARG (1); + size_t len = ARG_LEN (1); + if (strlen (str) < len) + m4_warn (0, me, _("argument %s truncated"), + quotearg_style_mem (locale_quoting_style, str, len)); + if (!debug_set_output (me, str)) + m4_warn (errno, me, _("cannot set debug file %s"), + quotearg_style (locale_quoting_style, str)); + } } /* This section contains text processing macros: "len", "index", @@ -1855,7 +1899,8 @@ m4_index (struct obstack *obs, int argc, macro_arguments *argv) haystack = ARG (1); haystack_len = ARG_LEN (1); needle = ARG (2); - if (!arg_empty (argv, 3) && !numeric_arg (arg_info (argv), ARG (3), &offset)) + if (!arg_empty (argv, 3) + && !numeric_arg (arg_info (argv), ARG (3), ARG_LEN (3), &offset)) return; if (offset < 0) { @@ -1907,7 +1952,7 @@ m4_substr (struct obstack *obs, int argc, macro_arguments *argv) } length = ARG_LEN (1); - if (!arg_empty (argv, 2) && !numeric_arg (me, ARG (2), &start)) + if (!arg_empty (argv, 2) && !numeric_arg (me, ARG (2), ARG_LEN (2), &start)) return; if (start < 0) start += length; @@ -1916,7 +1961,7 @@ m4_substr (struct obstack *obs, int argc, macro_arguments *argv) end = length; else { - if (!numeric_arg (me, ARG (3), &end)) + if (!numeric_arg (me, ARG (3), ARG_LEN (3), &end)) return; if (end < 0) end += length; @@ -2406,8 +2451,8 @@ m4_patsubst (struct obstack *obs, int argc, macro_arguments *argv) void m4_placeholder (struct obstack *obs, int argc, macro_arguments *argv) { - m4_warn (0, NULL, _("builtin `%s' requested by frozen file not found"), - ARG (0)); + m4_warn (0, NULL, _("builtin %s requested by frozen file not found"), + quotearg_style_mem (locale_quoting_style, ARG (0), ARG_LEN (0))); } /*-------------------------------------------------------------------------. diff --git a/src/debug.c b/src/debug.c index b97fca3..8ed2d0d 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1,7 +1,7 @@ /* GNU m4 -- A simple macro processor - Copyright (C) 1991, 1992, 1993, 1994, 2004, 2006, 2007, 2008 Free - Software Foundation, Inc. + Copyright (C) 1991, 1992, 1993, 1994, 2004, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. This file is part of GNU M4. @@ -43,25 +43,33 @@ debug_init (void) obstack_init (&trace); } -/*------------------------------------------------------------------. -| Function to decode the debugging flags OPTS. Used by main while | -| processing option -d, and by the builtin debugmode (). Return -1 | -| if the parse failed, otherwise change the debug level. | -`------------------------------------------------------------------*/ +/*-------------------------------------------------------------------. +| Function to decode the debugging flags OPTS of length LEN. If LEN | +| is SIZE_MAX, use strlen (OPTS) instead. Used by main while | +| processing option -d, and by the builtin debugmode. Return -1 if | +| the parse failed, otherwise change the debug level. | +`-------------------------------------------------------------------*/ int -debug_decode (const char *opts) +debug_decode (const char *opts, size_t len) { int level; char mode = '\0'; - if (opts == NULL || *opts == '\0') + if (!opts) + opts = ""; + if (len == SIZE_MAX) + len = strlen (opts); + if (!len) level = DEBUG_TRACE_DEFAULT | debug_level; else { if (*opts == '-' || *opts == '+') - mode = *opts++; - for (level = 0; *opts; opts++) + { + len--; + mode = *opts++; + } + for (level = 0; len--; opts++) { switch (*opts) { diff --git a/src/format.c b/src/format.c index 8b2b11a..09cffa3 100644 --- a/src/format.c +++ b/src/format.c @@ -27,24 +27,26 @@ 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 (const call_info *me, const char *str) +arg_int (const 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 (0, me, _("empty string treated as 0")); return 0; } errno = 0; value = strtol (str, &endp, 10); - if (*endp != '\0') - m4_warn (0, me, _("non-numeric argument `%s'"), str); + if (endp - str != len) + m4_warn (0, me, _("non-numeric argument %s"), + quotearg_style_mem (locale_quoting_style, str, len)); else if (isspace (to_uchar (*str))) m4_warn (0, me, _("leading whitespace ignored")); else if (errno == ERANGE || (int) value != value) @@ -52,24 +54,26 @@ arg_int (const 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 (const call_info *me, const char *str) +arg_long (const 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 (0, me, _("empty string treated as 0")); return 0L; } errno = 0; value = strtol (str, &endp, 10); - if (*endp != '\0') - m4_warn (0, me, _("non-numeric argument `%s'"), str); + if (endp - str != len) + m4_warn (0, me, _("non-numeric argument %s"), + quotearg_style_mem (locale_quoting_style, str, len)); else if (isspace (to_uchar (*str))) m4_warn (0, me, _("leading whitespace ignored")); else if (errno == ERANGE) @@ -77,22 +81,35 @@ arg_long (const 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 (const call_info *me, const char *str, size_t len) +{ + if (strlen (str) < len) + m4_warn (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 (const call_info *me, const char *str) +arg_double (const call_info *me, const char *str, size_t len) { char *endp; double value; - if (*str == '\0') + if (!len) { m4_warn (0, me, _("empty string treated as 0")); return 0.0; } errno = 0; value = strtod (str, &endp); - if (*endp != '\0') - m4_warn (0, me, _("non-numeric argument `%s'"), str); + if (endp - str != len) + m4_warn (0, me, _("non-numeric argument %s"), + quotearg_style_mem (locale_quoting_style, str, len)); else if (isspace (to_uchar (*str))) m4_warn (0, me, _("leading whitespace ignored")); else if (errno == ERANGE) @@ -101,16 +118,16 @@ arg_double (const call_info *me, const char *str) } #define ARG_INT(i, argc, argv) \ - ((argc <= ++i) ? 0 : arg_int (me, ARG (i))) + ((argc <= ++i) ? 0 : arg_int (me, ARG (i), ARG_LEN (i))) #define ARG_LONG(i, argc, argv) \ - ((argc <= ++i) ? 0L : arg_long (me, ARG (i))) + ((argc <= ++i) ? 0L : arg_long (me, ARG (i), ARG_LEN (i))) #define ARG_STR(i, argc, argv) \ - ((argc <= ++i) ? "" : ARG (i)) + ((argc <= ++i) ? "" : arg_string (me, ARG (i), ARG_LEN (i))) #define ARG_DOUBLE(i, argc, argv) \ - ((argc <= ++i) ? 0.0 : arg_double (me, ARG (i))) + ((argc <= ++i) ? 0.0 : arg_double (me, ARG (i), ARG_LEN (i))) /*------------------------------------------------------------------. diff --git a/src/freeze.c b/src/freeze.c index 2648e39..1502532 100644 --- a/src/freeze.c +++ b/src/freeze.c @@ -1,7 +1,7 @@ /* GNU m4 -- A simple macro processor - Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2006, 2007, 2008 - Free Software Foundation, Inc. + Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2006, 2007, 2008, + 2009 Free Software Foundation, Inc. This file is part of GNU M4. @@ -371,8 +371,13 @@ reload_frozen_state (const char *name) case 'F': - /* Enter a macro having a builtin function as a definition. */ - + /* Enter a macro having a builtin function as a + definition. No builtin contains NUL in the name. */ + if (strlen (string[1]) < number[1]) + m4_error (EXIT_FAILURE, 0, NULL, _("\ +ill-formed frozen file, invalid builtin %s encountered"), + quotearg_style_mem (locale_quoting_style, string[1], + number[1])); bp = find_builtin_by_name (string[1]); define_builtin (string[0], number[0], bp, SYMBOL_PUSHDEF); break; diff --git a/src/m4.c b/src/m4.c index 91842e4..ef244e3 100644 --- a/src/m4.c +++ b/src/m4.c @@ -480,7 +480,7 @@ main (int argc, char *const *argv, char *const *envp) break; case 'E': - debug_decode ("-d"); + debug_decode ("-d", SIZE_MAX); if (!fatal_warnings) fatal_warnings = true; else @@ -530,8 +530,9 @@ main (int argc, char *const *argv, char *const *envp) case 'd': if (seen_file) goto defer; - if (debug_decode (optarg) < 0) - error (0, 0, "bad debug flags: `%s'", optarg); + if (debug_decode (optarg, SIZE_MAX) < 0) + error (0, 0, "bad debug flags: %s", + quotearg_style (locale_quoting_style, optarg)); break; case 'e': @@ -603,7 +604,7 @@ main (int argc, char *const *argv, char *const *envp) if (interactive) { signal (SIGINT, SIG_IGN); - setbuf (stdout, (char *) NULL); + setbuf (stdout, NULL); } /* Handle deferred command line macro definitions. Must come after @@ -631,8 +632,9 @@ main (int argc, char *const *argv, char *const *envp) break; case 'd': - if (debug_decode (arg) < 0) - error (0, 0, "bad debug flags: `%s'", arg); + if (debug_decode (arg, SIZE_MAX) < 0) + error (0, 0, "bad debug flags: %s", + quotearg_style (locale_quoting_style, optarg)); break; case 't': diff --git a/src/m4.h b/src/m4.h index 0611db4..b5521ca 100644 --- a/src/m4.h +++ b/src/m4.h @@ -205,7 +205,7 @@ extern FILE *debug; #define DEBUG_TRACE_DEFAULT 0x407 void debug_init (void); -int debug_decode (const char *); +int debug_decode (const char *, size_t); void debug_flush_files (void); bool debug_set_output (const call_info *, const char *); void debug_message (const char *, ...) M4_GNUC_PRINTF (1, 2); diff --git a/src/path.c b/src/path.c index d630bad..0ed674c 100644 --- a/src/path.c +++ b/src/path.c @@ -1,7 +1,7 @@ /* GNU m4 -- A simple macro processor - Copyright (C) 1989, 1990, 1991, 1992, 1993, 2004, 2006, 2007, 2008 - Free Software Foundation, Inc. + Copyright (C) 1989, 1990, 1991, 1992, 1993, 2004, 2006, 2007, 2008, + 2009 Free Software Foundation, Inc. This file is part of GNU M4. @@ -176,7 +176,11 @@ m4_path_search (const char *file, char **result) if (fp != NULL) { if (debug_level & DEBUG_TRACE_PATH) - debug_message ("path search for `%s' found `%s'", file, name); + debug_message ("path search for %s found %s", + quotearg_style (locale_quoting_style, file), + quotearg_n_style (1, locale_quoting_style, name)); + if (set_cloexec_flag (fileno (fp), true) != 0) + m4_warn (errno, NULL, _("cannot protect input file across forks")); if (result) *result = name; else hooks/post-receive -- GNU M4 source repository
