diff options
author | Eric Blake <ebb9@byu.net> | 2008-02-06 12:01:29 -0700 |
---|---|---|
committer | Eric Blake <ebb9@byu.net> | 2008-02-06 12:01:29 -0700 |
commit | 4f1f438e49632dbd5c5061d8992498acea8cf4b3 (patch) | |
tree | 468836b0bc0cac814f4ecbf913c1b2bdad5a39cf /m4 | |
parent | 74f73804d6c375516ad834a9db980afea286fa4c (diff) | |
download | m4-4f1f438e49632dbd5c5061d8992498acea8cf4b3.tar.gz |
Fix security hole introduced 2007-11-23.
* m4/utility.c (m4_verror_at_line): Properly escape macro names.
* src/main.c (main): Manage quoteargs defaults.
* doc/m4.texinfo (Indir): Document and test this.
Signed-off-by: Eric Blake <ebb9@byu.net>
Diffstat (limited to 'm4')
-rw-r--r-- | m4/utility.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/m4/utility.c b/m4/utility.c index 69349fea..60b76446 100644 --- a/m4/utility.c +++ b/m4/utility.c @@ -24,6 +24,7 @@ #include "exitfail.h" #include "progname.h" +#include "quotearg.h" #include "verror.h" #include "xvasprintf.h" @@ -154,18 +155,37 @@ m4_verror_at_line (m4 *context, bool warn, int status, int errnum, const char *format, va_list args) { char *full = NULL; + char *safe_macro = NULL; + + /* Sanitize MACRO, sinze we are turning around and using it in a + format string. The allocation is overly conservative, but + problematic macro names only occur via indir or changesyntax. */ + if (macro && strchr (macro, '%')) + { + char *p = safe_macro = xcharalloc (2 * strlen (macro) + 1); + do + { + if (*macro == '%') + *p++ = '%'; + *p++ = *macro++; + } + while (*macro); + } /* Prepend warning and the macro name, as needed. But if that fails for non-memory reasons (unlikely), then still use the original format. */ if (warn && macro) - full = xasprintf (_("Warning: %s: %s"), macro, format); + full = xasprintf (_("Warning: %s: %s"), + quotearg (safe_macro ? safe_macro : macro), format); else if (warn) full = xasprintf (_("Warning: %s"), format); else if (macro) - full = xasprintf (_("%s: %s"), macro, format); + full = xasprintf (_("%s: %s"), + quotearg (safe_macro ? safe_macro : macro), format); verror_at_line (status, errnum, line ? file : NULL, line, full ? full : format, args); free (full); + free (safe_macro); if ((!warn || m4_get_fatal_warnings_opt (context)) && !m4_get_exit_status (context)) m4_set_exit_status (context, EXIT_FAILURE); |