mirror of
https://github.com/mirror/make.git
synced 2025-03-26 12:04:42 +08:00
Use strtol() instead of atoi()
strtol() is part of C89 and a fallback is provided by gnulib. * src/function.c (func_word, func_wordlist): Change atoi to strtol. * test/scripts/functions/word: Add out-of-range verification testing.
This commit is contained in:
parent
f3ad572099
commit
d9291d09b8
@ -51,4 +51,5 @@ getloadavg
|
|||||||
host-cpu-c-abi
|
host-cpu-c-abi
|
||||||
mempcpy
|
mempcpy
|
||||||
strerror
|
strerror
|
||||||
|
strtol
|
||||||
make-glob"
|
make-glob"
|
||||||
|
@ -765,35 +765,36 @@ strip_whitespace (const char **begpp, const char **endpp)
|
|||||||
return (char *)*begpp;
|
return (char *)*begpp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static long
|
||||||
check_numeric (const char *s, const char *msg)
|
parse_numeric (const char *s, const char *msg)
|
||||||
{
|
{
|
||||||
const char *end = s + strlen (s) - 1;
|
|
||||||
const char *beg = s;
|
const char *beg = s;
|
||||||
strip_whitespace (&s, &end);
|
const char *end = s + strlen (s) - 1;
|
||||||
|
char *endp;
|
||||||
|
long num;
|
||||||
|
strip_whitespace (&beg, &end);
|
||||||
|
|
||||||
for (; s <= end; ++s)
|
errno = 0;
|
||||||
if (!ISDIGIT (*s)) /* ISDIGIT only evals its arg once: see makeint.h. */
|
num = strtol (beg, &endp, 10);
|
||||||
break;
|
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);
|
||||||
|
|
||||||
if (s <= end || end - beg < 0)
|
return num;
|
||||||
OSS (fatal, *expanding_var, "%s: '%s'", msg, beg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
func_word (char *o, char **argv, const char *funcname UNUSED)
|
func_word (char *o, char **argv, const char *funcname UNUSED)
|
||||||
{
|
{
|
||||||
const char *end_p;
|
const char *end_p;
|
||||||
const char *p;
|
const char *p;
|
||||||
int i;
|
long i;
|
||||||
|
|
||||||
/* Check the first argument. */
|
i = parse_numeric (argv[0],
|
||||||
check_numeric (argv[0], _("non-numeric first argument to 'word' function"));
|
_("non-numeric first argument to 'word' function"));
|
||||||
i = atoi (argv[0]);
|
if (i <= 0)
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
O (fatal, *expanding_var,
|
O (fatal, *expanding_var,
|
||||||
_("first argument to 'word' function must be greater than 0"));
|
_("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 *
|
static char *
|
||||||
func_wordlist (char *o, char **argv, const char *funcname UNUSED)
|
func_wordlist (char *o, char **argv, const char *funcname UNUSED)
|
||||||
{
|
{
|
||||||
int start, count;
|
long start, stop, count;
|
||||||
|
|
||||||
/* Check the arguments. */
|
start = parse_numeric (argv[0],
|
||||||
check_numeric (argv[0],
|
_("non-numeric first argument to 'wordlist' function"));
|
||||||
_("non-numeric first argument to 'wordlist' function"));
|
stop = parse_numeric (argv[1],
|
||||||
check_numeric (argv[1],
|
_("non-numeric second argument to 'wordlist' function"));
|
||||||
_("non-numeric second argument to 'wordlist' function"));
|
|
||||||
|
|
||||||
start = atoi (argv[0]);
|
|
||||||
if (start < 1)
|
if (start < 1)
|
||||||
ON (fatal, *expanding_var,
|
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)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,7 @@ run_make_test('FOO = foo bar biz baz
|
|||||||
word-e1: ; @echo $(word ,$(FOO))
|
word-e1: ; @echo $(word ,$(FOO))
|
||||||
word-e2: ; @echo $(word abc ,$(FOO))
|
word-e2: ; @echo $(word abc ,$(FOO))
|
||||||
word-e3: ; @echo $(word 1a,$(FOO))
|
word-e3: ; @echo $(word 1a,$(FOO))
|
||||||
|
word-e4: ; @echo $(word 9999999999999999999,$(FOO))
|
||||||
|
|
||||||
wordlist-e1: ; @echo $(wordlist ,,$(FOO))
|
wordlist-e1: ; @echo $(wordlist ,,$(FOO))
|
||||||
wordlist-e2: ; @echo $(wordlist abc ,,$(FOO))
|
wordlist-e2: ; @echo $(wordlist abc ,,$(FOO))
|
||||||
@ -69,19 +70,24 @@ run_make_test(undef,
|
|||||||
"#MAKEFILE#:5: *** non-numeric first argument to 'word' function: '1a'. Stop.",
|
"#MAKEFILE#:5: *** non-numeric first argument to 'word' function: '1a'. Stop.",
|
||||||
512);
|
512);
|
||||||
|
|
||||||
|
run_make_test(undef,
|
||||||
|
'word-e4',
|
||||||
|
"#MAKEFILE#:6: *** Numerical result out of range: '9999999999999999999'. Stop.",
|
||||||
|
512);
|
||||||
|
|
||||||
run_make_test(undef,
|
run_make_test(undef,
|
||||||
'wordlist-e1',
|
'wordlist-e1',
|
||||||
"#MAKEFILE#:7: *** non-numeric first argument to 'wordlist' function: ''. Stop.",
|
"#MAKEFILE#:8: *** non-numeric first argument to 'wordlist' function: ''. Stop.",
|
||||||
512);
|
512);
|
||||||
|
|
||||||
run_make_test(undef,
|
run_make_test(undef,
|
||||||
'wordlist-e2',
|
'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);
|
512);
|
||||||
|
|
||||||
run_make_test(undef,
|
run_make_test(undef,
|
||||||
'wordlist-e3',
|
'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);
|
512);
|
||||||
|
|
||||||
# Test error conditions again, but this time in a variable reference
|
# Test error conditions again, but this time in a variable reference
|
||||||
|
Loading…
Reference in New Issue
Block a user