summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2009-02-05 07:47:32 -0700
committerEric Blake <ebb9@byu.net>2009-02-11 13:55:56 -0700
commit185b10ba33786707f6478b8315e9527151f60902 (patch)
tree9c5c858994526ccdfe33612b1a775685c81949ef
parent052319b635abea0efba90930031d9c0899dcb0a8 (diff)
downloadm4-185b10ba33786707f6478b8315e9527151f60902.tar.gz
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 <ebb9@byu.net>
-rw-r--r--ChangeLog22
-rw-r--r--doc/m4.texinfo2
-rw-r--r--m4/m4module.h4
-rw-r--r--m4/utility.c24
-rw-r--r--modules/evalparse.c7
-rw-r--r--modules/gnu.c7
-rw-r--r--modules/m4.c29
-rw-r--r--modules/stdlib.c13
-rw-r--r--modules/time.c31
-rw-r--r--tests/null.errbin1318 -> 2045 bytes
-rw-r--r--tests/null.m4bin7559 -> 7735 bytes
-rw-r--r--tests/null.outbin607 -> 613 bytes
-rw-r--r--tests/others.at8
13 files changed, 99 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index acbdeec5..def85f5c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
2009-02-11 Eric Blake <ebb9@byu.net>
+ 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 <ebb9@byu.net>
+
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 f972b48b..62fed45f 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -5751,7 +5751,7 @@ parenthesis will match any close parenthesis, etc.
@example
changesyntax(`(@{<', `)@}>', `,;:', `O(,)')
@result{}
-eval@{2**4-1; 2 : 8>
+eval@{2**4-1; 2: 8>
@result{}00001111
@end example
diff --git a/m4/m4module.h b/m4/m4module.h
index d5ad5135..84c203e5 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,7 +170,7 @@ 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);
extern m4_symbol *m4_symbol_value_lookup (m4 *, m4_macro_args *, size_t, bool);
diff --git a/m4/utility.c b/m4/utility.c
index 31c17051..6d19526f 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,30 +68,36 @@ 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;
}
diff --git a/modules/evalparse.c b/modules/evalparse.c
index ac30cfe9..87a318e2 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/gnu.c b/modules/gnu.c
index 8ad17225..ce14532b 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.
@@ -599,7 +599,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. */
diff --git a/modules/m4.c b/modules/m4.c
index 177590dc..44e8a0ae 100644
--- a/modules/m4.c
+++ b/modules/m4.c
@@ -536,7 +536,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 +547,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 +565,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 +594,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 +616,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));
}
}
@@ -824,7 +831,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 +927,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 +976,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 +985,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 b60e977a..3fce71f8 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 a922a677..ee193a7b 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/tests/null.err b/tests/null.err
index 7b9f7981..edad891e 100644
--- a/tests/null.err
+++ b/tests/null.err
Binary files differ
diff --git a/tests/null.m4 b/tests/null.m4
index f7a15875..3d57806e 100644
--- a/tests/null.m4
+++ b/tests/null.m4
Binary files differ
diff --git a/tests/null.out b/tests/null.out
index 97f80dd5..cfb78c04 100644
--- a/tests/null.out
+++ b/tests/null.out
Binary files differ
diff --git a/tests/others.at b/tests/others.at
index 6776ee36..3f123516 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.
#
@@ -432,8 +433,11 @@ dnl all but m4exit
AT_CHECK_M4([-Dm4exit -I "$abs_srcdir" null.m4], [0], [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