]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Use strtol() instead of atoi()
authorJouke Witteveen <j.witteveen@gmail.com>
Fri, 16 Jul 2021 12:04:33 +0000 (14:04 +0200)
committerPaul Smith <psmith@gnu.org>
Sun, 28 Nov 2021 19:26:28 +0000 (14:26 -0500)
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.

bootstrap.conf
src/function.c
tests/scripts/functions/word

index bd37f1b918b53a96cdfe2808850cc7d08bd98212..69058aa0728196bfa427b1d0374b2c46a7e93a9c 100644 (file)
@@ -51,4 +51,5 @@ getloadavg
 host-cpu-c-abi
 mempcpy
 strerror
+strtol
 make-glob"
index 5a7ad3a590524644334843b6002ab040e86bf60b..b870cbffb795636fd77b672305b86f8b405aabdb 100644 (file)
@@ -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)
     {
index 4dcc940652a6cd977d53d1b3addd02c1e7cdde37..044bc947d32f3fb84fc5dfb4e6db864f89474b28 100644 (file)
@@ -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))
@@ -69,19 +70,24 @@ run_make_test(undef,
               "#MAKEFILE#:5: *** non-numeric first argument to 'word' function: '1a'.  Stop.",
               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