Commit 66806d24 by Serge Hallyn Committed by GitHub

Merge pull request #1551 from brauner/2017-05-11/fix_num_parsing

utils: fix num parsing functions
parents fbe5c36e 15fe2189
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "config.h" #include "config.h"
#include <ctype.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -1998,12 +1999,18 @@ int lxc_safe_uint(const char *numstr, unsigned int *converted) ...@@ -1998,12 +1999,18 @@ int lxc_safe_uint(const char *numstr, unsigned int *converted)
char *err = NULL; char *err = NULL;
unsigned long int uli; unsigned long int uli;
while (isspace(*numstr))
numstr++;
if (*numstr == '-')
return -EINVAL;
errno = 0; errno = 0;
uli = strtoul(numstr, &err, 0); uli = strtoul(numstr, &err, 0);
if (errno > 0) if (errno == ERANGE && uli == ULONG_MAX)
return -errno; return -errno;
if (!err || err == numstr || *err != '\0') if (err == numstr || *err != '\0')
return -EINVAL; return -EINVAL;
if (uli > UINT_MAX) if (uli > UINT_MAX)
...@@ -2020,13 +2027,16 @@ int lxc_safe_int(const char *numstr, int *converted) ...@@ -2020,13 +2027,16 @@ int lxc_safe_int(const char *numstr, int *converted)
errno = 0; errno = 0;
sli = strtol(numstr, &err, 0); sli = strtol(numstr, &err, 0);
if (errno > 0) if (errno == ERANGE && (sli == LONG_MAX || sli == LONG_MIN))
return -errno;
if (errno != 0 && sli == 0)
return -errno; return -errno;
if (!err || err == numstr || *err != '\0') if (err == numstr || *err != '\0')
return -EINVAL; return -EINVAL;
if (sli > INT_MAX) if (sli > INT_MAX || sli < INT_MIN)
return -ERANGE; return -ERANGE;
*converted = (int)sli; *converted = (int)sli;
...@@ -2040,14 +2050,14 @@ int lxc_safe_long(const char *numstr, long int *converted) ...@@ -2040,14 +2050,14 @@ int lxc_safe_long(const char *numstr, long int *converted)
errno = 0; errno = 0;
sli = strtol(numstr, &err, 0); sli = strtol(numstr, &err, 0);
if (errno > 0) if (errno == ERANGE && (sli == LONG_MAX || sli == LONG_MIN))
return -errno; return -errno;
if (!err || err == numstr || *err != '\0') if (errno != 0 && sli == 0)
return -EINVAL; return -errno;
if (sli > LONG_MAX) if (err == numstr || *err != '\0')
return -ERANGE; return -EINVAL;
*converted = sli; *converted = sli;
return 0; return 0;
......
...@@ -228,7 +228,22 @@ non_test_error: ...@@ -228,7 +228,22 @@ non_test_error:
void test_lxc_safe_uint(void) void test_lxc_safe_uint(void)
{ {
int ret;
unsigned int n; unsigned int n;
char numstr[LXC_NUMSTRLEN64];
lxc_test_assert_abort((-EINVAL == lxc_safe_uint(" -123", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint("-123", &n)));
ret = snprintf(numstr, LXC_NUMSTRLEN64, "%" PRIu64, (uint64_t)UINT_MAX);
if (ret < 0 || ret >= LXC_NUMSTRLEN64)
exit(EXIT_FAILURE);
lxc_test_assert_abort((0 == lxc_safe_uint(numstr, &n)) && n == UINT_MAX);
ret = snprintf(numstr, LXC_NUMSTRLEN64, "%" PRIu64, (uint64_t)UINT_MAX + 1);
if (ret < 0 || ret >= LXC_NUMSTRLEN64)
exit(EXIT_FAILURE);
lxc_test_assert_abort((-ERANGE == lxc_safe_uint(numstr, &n)));
lxc_test_assert_abort((0 == lxc_safe_uint("1234345", &n)) && n == 1234345); lxc_test_assert_abort((0 == lxc_safe_uint("1234345", &n)) && n == 1234345);
lxc_test_assert_abort((0 == lxc_safe_uint(" 345", &n)) && n == 345); lxc_test_assert_abort((0 == lxc_safe_uint(" 345", &n)) && n == 345);
...@@ -247,7 +262,29 @@ void test_lxc_safe_uint(void) ...@@ -247,7 +262,29 @@ void test_lxc_safe_uint(void)
void test_lxc_safe_int(void) void test_lxc_safe_int(void)
{ {
int ret;
signed int n; signed int n;
char numstr[LXC_NUMSTRLEN64];
ret = snprintf(numstr, LXC_NUMSTRLEN64, "%" PRIu64, (uint64_t)INT_MAX);
if (ret < 0 || ret >= LXC_NUMSTRLEN64)
exit(EXIT_FAILURE);
lxc_test_assert_abort((0 == lxc_safe_int(numstr, &n)) && n == INT_MAX);
ret = snprintf(numstr, LXC_NUMSTRLEN64, "%" PRIu64, (uint64_t)INT_MAX + 1);
if (ret < 0 || ret >= LXC_NUMSTRLEN64)
exit(EXIT_FAILURE);
lxc_test_assert_abort((-ERANGE == lxc_safe_int(numstr, &n)));
ret = snprintf(numstr, LXC_NUMSTRLEN64, "%" PRId64, (int64_t)INT_MIN);
if (ret < 0 || ret >= LXC_NUMSTRLEN64)
exit(EXIT_FAILURE);
lxc_test_assert_abort((0 == lxc_safe_int(numstr, &n)) && n == INT_MIN);
ret = snprintf(numstr, LXC_NUMSTRLEN64, "%" PRId64, (int64_t)INT_MIN - 1);
if (ret < 0 || ret >= LXC_NUMSTRLEN64)
exit(EXIT_FAILURE);
lxc_test_assert_abort((-ERANGE == lxc_safe_int(numstr, &n)));
lxc_test_assert_abort((0 == lxc_safe_int("1234345", &n)) && n == 1234345); lxc_test_assert_abort((0 == lxc_safe_int("1234345", &n)) && n == 1234345);
lxc_test_assert_abort((0 == lxc_safe_int(" 345", &n)) && n == 345); lxc_test_assert_abort((0 == lxc_safe_int(" 345", &n)) && n == 345);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment