diff --git a/src/arscan.c b/src/arscan.c
index b94f283d..83377910 100644
--- a/src/arscan.c
+++ b/src/arscan.c
@@ -441,7 +441,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
# endif
#endif
char *namemap = 0;
- int namemap_size = 0;
+ unsigned int namemap_size = 0;
int desc = open (archive, O_RDONLY, 0);
if (desc < 0)
return -1;
@@ -541,7 +541,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
while (1)
{
- int nread;
+ ssize_t nread;
struct ar_hdr member_header;
#ifdef AIAMAGBIG
struct ar_hdr_big member_header_big;
@@ -696,10 +696,11 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
&& (name[0] == ' ' || name[0] == '/')
&& namemap != 0)
{
- int name_off = atoi (name + 1);
- int name_len;
+ const char* err;
+ unsigned int name_off = make_toui (name + 1, &err);
+ size_t name_len;
- if (name_off < 0 || name_off >= namemap_size)
+ if (err|| name_off >= namemap_size)
goto invalid;
name = namemap + name_off;
@@ -712,9 +713,10 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
&& name[1] == '1'
&& name[2] == '/')
{
- int name_len = atoi (name + 3);
+ const char* err;
+ unsigned int name_len = make_toui (name + 3, &err);
- if (name_len < 1)
+ if (err || name_len == 0 || name_len > PATH_MAX)
goto invalid;
name = alloca (name_len + 1);
diff --git a/src/job.c b/src/job.c
index 6060cad8..d24288ac 100644
--- a/src/job.c
+++ b/src/job.c
@@ -2065,8 +2065,8 @@ load_too_high (void)
if (p && ISDIGIT(p[1]))
{
- int cnt = atoi (p+1);
- DB (DB_JOBS, ("Running: system = %d / make = %u (max requested = %f)\n",
+ unsigned int cnt = make_toui (p+1, NULL);
+ DB (DB_JOBS, ("Running: system = %u / make = %u (max requested = %f)\n",
cnt, job_slots_used, max_load_average));
return (double)cnt > max_load_average;
}
diff --git a/src/main.c b/src/main.c
index 829824bb..0d2dff72 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1411,7 +1411,7 @@ main (int argc, char **argv, char **envp)
OUTPUT_TRACED ();
++ep;
}
- restarts = (unsigned int) atoi (ep);
+ restarts = make_toui (ep, NULL);
export = v_noexport;
}
@@ -1536,7 +1536,7 @@ main (int argc, char **argv, char **envp)
{
struct variable *v = lookup_variable (STRING_SIZE_TUPLE (MAKELEVEL_NAME));
if (v && v->value[0] != '\0' && v->value[0] != '-')
- makelevel = (unsigned int) atoi (v->value);
+ makelevel = make_toui (v->value, NULL);
else
makelevel = 0;
}
@@ -3187,14 +3187,10 @@ decode_switches (int argc, const char **argv, int env)
if (coptarg)
{
- int i = atoi (coptarg);
- const char *cp;
+ const char *err;
+ unsigned int i = make_toui (coptarg, &err);
- /* Yes, I realize we're repeating this in some cases. */
- for (cp = coptarg; ISDIGIT (cp[0]); ++cp)
- ;
-
- if (i < 1 || cp[0] != '\0')
+ if (err || i == 0)
{
error (NILF, 0,
_("the '-%c' option requires a positive integer argument"),
diff --git a/src/makeint.h b/src/makeint.h
index 6bcb0c2c..bb013fd1 100644
--- a/src/makeint.h
+++ b/src/makeint.h
@@ -541,6 +541,7 @@ void die (int) NORETURN;
void pfatal_with_name (const char *) NORETURN;
void perror_with_name (const char *, const char *);
#define xstrlen(_s) ((_s)==NULL ? 0 : strlen (_s))
+unsigned int make_toui (const char*, const char**);
pid_t make_pid ();
void *xmalloc (size_t);
void *xcalloc (size_t);
diff --git a/src/misc.c b/src/misc.c
index b03f2a3a..624cd058 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -34,6 +34,25 @@ this program. If not, see . */
# include
#endif
+unsigned int
+make_toui (const char *str, const char **error)
+{
+ char *end;
+ unsigned long val = strtoul (str, &end, 10);
+
+ if (error)
+ {
+ if (str[0] == '\0')
+ *error = "Missing value";
+ else if (*end != '\0')
+ *error = "Invalid value";
+ else
+ *error = NULL;
+ }
+
+ return val;
+}
+
/* Compare strings *S1 and *S2.
Return negative if the first is less, positive if it is greater,
zero if they are equal. */