cutils: work around platform differences in strto{l,ul,ll,ull}
Linux returns 0 if no conversion was made, while OS X and presumably the BSDs return EINVAL. The OS X convention rejects more invalid inputs, so convert to it and adjust the test case. Windows returns 1 from strtoul and strtoull (instead of -1) for negative out-of-range input; fix it up. Reported-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
9fd1a94888
commit
47d4be12c3
@ -264,9 +264,7 @@ static void test_qemu_strtol_empty(void)
|
||||
|
||||
err = qemu_strtol(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtol_whitespace(void)
|
||||
@ -279,9 +277,7 @@ static void test_qemu_strtol_whitespace(void)
|
||||
|
||||
err = qemu_strtol(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtol_invalid(void)
|
||||
@ -294,9 +290,7 @@ static void test_qemu_strtol_invalid(void)
|
||||
|
||||
err = qemu_strtol(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtol_trailing(void)
|
||||
@ -478,8 +472,7 @@ static void test_qemu_strtol_full_empty(void)
|
||||
|
||||
err = qemu_strtol(str, NULL, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtol_full_negative(void)
|
||||
@ -555,9 +548,7 @@ static void test_qemu_strtoul_empty(void)
|
||||
|
||||
err = qemu_strtoul(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoul_whitespace(void)
|
||||
@ -570,9 +561,7 @@ static void test_qemu_strtoul_whitespace(void)
|
||||
|
||||
err = qemu_strtoul(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoul_invalid(void)
|
||||
@ -585,8 +574,7 @@ static void test_qemu_strtoul_invalid(void)
|
||||
|
||||
err = qemu_strtoul(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoul_trailing(void)
|
||||
@ -765,8 +753,7 @@ static void test_qemu_strtoul_full_empty(void)
|
||||
|
||||
err = qemu_strtoul(str, NULL, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
static void test_qemu_strtoul_full_negative(void)
|
||||
{
|
||||
@ -840,9 +827,7 @@ static void test_qemu_strtoll_empty(void)
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_whitespace(void)
|
||||
@ -855,9 +840,7 @@ static void test_qemu_strtoll_whitespace(void)
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_invalid(void)
|
||||
@ -870,8 +853,7 @@ static void test_qemu_strtoll_invalid(void)
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_trailing(void)
|
||||
@ -1050,8 +1032,7 @@ static void test_qemu_strtoll_full_empty(void)
|
||||
|
||||
err = qemu_strtoll(str, NULL, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_full_negative(void)
|
||||
@ -1128,9 +1109,7 @@ static void test_qemu_strtoull_empty(void)
|
||||
|
||||
err = qemu_strtoull(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoull_whitespace(void)
|
||||
@ -1143,9 +1122,7 @@ static void test_qemu_strtoull_whitespace(void)
|
||||
|
||||
err = qemu_strtoull(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoull_invalid(void)
|
||||
@ -1158,8 +1135,7 @@ static void test_qemu_strtoull_invalid(void)
|
||||
|
||||
err = qemu_strtoull(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoull_trailing(void)
|
||||
@ -1338,8 +1314,7 @@ static void test_qemu_strtoull_full_empty(void)
|
||||
|
||||
err = qemu_strtoull(str, NULL, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoull_full_negative(void)
|
||||
|
@ -361,9 +361,15 @@ int64_t strtosz(const char *nptr, char **end)
|
||||
/**
|
||||
* Helper function for qemu_strto*l() functions.
|
||||
*/
|
||||
static int check_strtox_error(const char **next, char *endptr,
|
||||
static int check_strtox_error(const char *p, char *endptr, const char **next,
|
||||
int err)
|
||||
{
|
||||
/* If no conversion was performed, prefer BSD behavior over glibc
|
||||
* behavior.
|
||||
*/
|
||||
if (err == 0 && endptr == p) {
|
||||
err = EINVAL;
|
||||
}
|
||||
if (!next && *endptr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -412,7 +418,7 @@ int qemu_strtol(const char *nptr, const char **endptr, int base,
|
||||
} else {
|
||||
errno = 0;
|
||||
*result = strtol(nptr, &p, base);
|
||||
err = check_strtox_error(endptr, p, errno);
|
||||
err = check_strtox_error(nptr, p, endptr, errno);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
@ -443,7 +449,11 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base,
|
||||
} else {
|
||||
errno = 0;
|
||||
*result = strtoul(nptr, &p, base);
|
||||
err = check_strtox_error(endptr, p, errno);
|
||||
/* Windows returns 1 for negative out-of-range values. */
|
||||
if (errno == ERANGE) {
|
||||
*result = -1;
|
||||
}
|
||||
err = check_strtox_error(nptr, p, endptr, errno);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
@ -466,7 +476,7 @@ int qemu_strtoll(const char *nptr, const char **endptr, int base,
|
||||
} else {
|
||||
errno = 0;
|
||||
*result = strtoll(nptr, &p, base);
|
||||
err = check_strtox_error(endptr, p, errno);
|
||||
err = check_strtox_error(nptr, p, endptr, errno);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
@ -489,7 +499,11 @@ int qemu_strtoull(const char *nptr, const char **endptr, int base,
|
||||
} else {
|
||||
errno = 0;
|
||||
*result = strtoull(nptr, &p, base);
|
||||
err = check_strtox_error(endptr, p, errno);
|
||||
/* Windows returns 1 for negative out-of-range values. */
|
||||
if (errno == ERANGE) {
|
||||
*result = -1;
|
||||
}
|
||||
err = check_strtox_error(nptr, p, endptr, errno);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user