[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[SCM] GNU M4 source repository branch, branch-1.6, updated. v1.5.89a-90-
From: |
Eric Blake |
Subject: |
[SCM] GNU M4 source repository branch, branch-1.6, updated. v1.5.89a-90-g1b5e601 |
Date: |
Thu, 12 Feb 2009 03:30:35 +0000 |
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 <address@hidden>
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 <address@hidden>
(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 <address@hidden>
+ 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 <address@hidden>
+
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
address@hidden status: 1
@example
define(`m4exit')include(`null.m4')dnl
@end example
address@hidden status: 2
address@hidden status: 1
@example
include(`null.m4')
@result{}# This file tests m4 behavior on NUL bytes.
address@hidden: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
address@hidden:stdin:3: Warning: maketemp: recommend using mkstemp instead
ifelse(esyscmd(`echo \` foo-?????? \''), ` foo-?????? ',
`no file', `created')
@result{}created
define(`file2', maketemp(`foo-XX'))dnl
address@hidden: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
+
address@hidden Do we reject unexpected NUL bytes?
+
address@hidden
+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
address@hidden:in.m4f:4: ill-formed frozen file, invalid builtin `len\0'
encountered
address@hidden
address@hidden 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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [SCM] GNU M4 source repository branch, branch-1.6, updated. v1.5.89a-90-g1b5e601,
Eric Blake <=