summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstrap.conf1
-rw-r--r--src/function.c53
-rw-r--r--tests/scripts/functions/word12
3 files changed, 36 insertions, 30 deletions
diff --git a/bootstrap.conf b/bootstrap.conf
index bd37f1b9..69058aa0 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -51,4 +51,5 @@ getloadavg
host-cpu-c-abi
mempcpy
strerror
+strtol
make-glob"
diff --git a/src/function.c b/src/function.c
index 5a7ad3a5..b870cbff 100644
--- a/src/function.c
+++ b/src/function.c
@@ -765,35 +765,36 @@ strip_whitespace (const char **begpp, const char **endpp)
return (char *)*begpp;
}
-static void
-check_numeric (const char *s, const char *msg)
+static long
+parse_numeric (const char *s, const char *msg)
{
- const char *end = s + strlen (s) - 1;
const char *beg = s;
- strip_whitespace (&s, &end);
-
- for (; s <= end; ++s)
- if (!ISDIGIT (*s)) /* ISDIGIT only evals its arg once: see makeint.h. */
- break;
+ const char *end = s + strlen (s) - 1;
+ char *endp;
+ long num;
+ strip_whitespace (&beg, &end);
- if (s <= end || end - beg < 0)
- OSS (fatal, *expanding_var, "%s: '%s'", msg, beg);
+ errno = 0;
+ num = strtol (beg, &endp, 10);
+ if (errno == ERANGE)
+ OSS (fatal, *expanding_var, "%s: '%s'", strerror (errno), s);
+ else if (endp == beg || endp <= end)
+ /* Empty or non-numeric input */
+ OSS (fatal, *expanding_var, "%s: '%s'", msg, s);
+
+ return num;
}
-
-
static char *
func_word (char *o, char **argv, const char *funcname UNUSED)
{
const char *end_p;
const char *p;
- int i;
+ long i;
- /* Check the first argument. */
- check_numeric (argv[0], _("non-numeric first argument to 'word' function"));
- i = atoi (argv[0]);
-
- if (i == 0)
+ i = parse_numeric (argv[0],
+ _("non-numeric first argument to 'word' function"));
+ if (i <= 0)
O (fatal, *expanding_var,
_("first argument to 'word' function must be greater than 0"));
@@ -811,20 +812,18 @@ func_word (char *o, char **argv, const char *funcname UNUSED)
static char *
func_wordlist (char *o, char **argv, const char *funcname UNUSED)
{
- int start, count;
+ long start, stop, count;
- /* Check the arguments. */
- check_numeric (argv[0],
- _("non-numeric first argument to 'wordlist' function"));
- check_numeric (argv[1],
- _("non-numeric second argument to 'wordlist' function"));
+ start = parse_numeric (argv[0],
+ _("non-numeric first argument to 'wordlist' function"));
+ stop = parse_numeric (argv[1],
+ _("non-numeric second argument to 'wordlist' function"));
- start = atoi (argv[0]);
if (start < 1)
ON (fatal, *expanding_var,
- "invalid first argument to 'wordlist' function: '%d'", start);
+ "invalid first argument to 'wordlist' function: '%ld'", start);
- count = atoi (argv[1]) - start + 1;
+ count = stop - start + 1;
if (count > 0)
{
diff --git a/tests/scripts/functions/word b/tests/scripts/functions/word
index 4dcc9406..044bc947 100644
--- a/tests/scripts/functions/word
+++ b/tests/scripts/functions/word
@@ -51,6 +51,7 @@ run_make_test('FOO = foo bar biz baz
word-e1: ; @echo $(word ,$(FOO))
word-e2: ; @echo $(word abc ,$(FOO))
word-e3: ; @echo $(word 1a,$(FOO))
+word-e4: ; @echo $(word 9999999999999999999,$(FOO))
wordlist-e1: ; @echo $(wordlist ,,$(FOO))
wordlist-e2: ; @echo $(wordlist abc ,,$(FOO))
@@ -70,18 +71,23 @@ run_make_test(undef,
512);
run_make_test(undef,
+ 'word-e4',
+ "#MAKEFILE#:6: *** Numerical result out of range: '9999999999999999999'. Stop.",
+ 512);
+
+run_make_test(undef,
'wordlist-e1',
- "#MAKEFILE#:7: *** non-numeric first argument to 'wordlist' function: ''. Stop.",
+ "#MAKEFILE#:8: *** non-numeric first argument to 'wordlist' function: ''. Stop.",
512);
run_make_test(undef,
'wordlist-e2',
- "#MAKEFILE#:8: *** non-numeric first argument to 'wordlist' function: 'abc '. Stop.",
+ "#MAKEFILE#:9: *** non-numeric first argument to 'wordlist' function: 'abc '. Stop.",
512);
run_make_test(undef,
'wordlist-e3',
- "#MAKEFILE#:9: *** non-numeric second argument to 'wordlist' function: ' 12a '. Stop.",
+ "#MAKEFILE#:10: *** non-numeric second argument to 'wordlist' function: ' 12a '. Stop.",
512);
# Test error conditions again, but this time in a variable reference