utils: Work around mingw strto*l bug with 0x
Mingw recognizes that "0x" has value 0 without setting errno, but
fails to advance endptr to the trailing garbage 'x'. This in turn
showed up in our recent testsuite additions for qemu_strtosz (commit
1657ba44b4
utils: Enhance testsuite for do_strtosz()); adjust our
remaining tests to show that we now work around this windows bug.
This patch intentionally fails check-syntax for use of strtol.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210317143325.2165821-3-eblake@redhat.com>
Message-Id: <20210323165308.15244-15-alex.bennee@linaro.org>
This commit is contained in:
parent
061d79097c
commit
6162f7dafe
@ -378,6 +378,15 @@ static void test_qemu_strtoi_hex(void)
|
|||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0x123);
|
g_assert_cmpint(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
g_assert(endptr == str + strlen(str));
|
||||||
|
|
||||||
|
str = "0x";
|
||||||
|
res = 999;
|
||||||
|
endptr = &f;
|
||||||
|
err = qemu_strtoi(str, &endptr, 16, &res);
|
||||||
|
|
||||||
|
g_assert_cmpint(err, ==, 0);
|
||||||
|
g_assert_cmpint(res, ==, 0);
|
||||||
|
g_assert(endptr == str + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_qemu_strtoi_max(void)
|
static void test_qemu_strtoi_max(void)
|
||||||
@ -669,6 +678,15 @@ static void test_qemu_strtoui_hex(void)
|
|||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmphex(res, ==, 0x123);
|
g_assert_cmphex(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
g_assert(endptr == str + strlen(str));
|
||||||
|
|
||||||
|
str = "0x";
|
||||||
|
res = 999;
|
||||||
|
endptr = &f;
|
||||||
|
err = qemu_strtoui(str, &endptr, 16, &res);
|
||||||
|
|
||||||
|
g_assert_cmpint(err, ==, 0);
|
||||||
|
g_assert_cmphex(res, ==, 0);
|
||||||
|
g_assert(endptr == str + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_qemu_strtoui_max(void)
|
static void test_qemu_strtoui_max(void)
|
||||||
@ -955,6 +973,15 @@ static void test_qemu_strtol_hex(void)
|
|||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0x123);
|
g_assert_cmpint(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
g_assert(endptr == str + strlen(str));
|
||||||
|
|
||||||
|
str = "0x";
|
||||||
|
res = 999;
|
||||||
|
endptr = &f;
|
||||||
|
err = qemu_strtol(str, &endptr, 16, &res);
|
||||||
|
|
||||||
|
g_assert_cmpint(err, ==, 0);
|
||||||
|
g_assert_cmpint(res, ==, 0);
|
||||||
|
g_assert(endptr == str + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_qemu_strtol_max(void)
|
static void test_qemu_strtol_max(void)
|
||||||
@ -1244,6 +1271,15 @@ static void test_qemu_strtoul_hex(void)
|
|||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmphex(res, ==, 0x123);
|
g_assert_cmphex(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
g_assert(endptr == str + strlen(str));
|
||||||
|
|
||||||
|
str = "0x";
|
||||||
|
res = 999;
|
||||||
|
endptr = &f;
|
||||||
|
err = qemu_strtoul(str, &endptr, 16, &res);
|
||||||
|
|
||||||
|
g_assert_cmpint(err, ==, 0);
|
||||||
|
g_assert_cmphex(res, ==, 0);
|
||||||
|
g_assert(endptr == str + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_qemu_strtoul_max(void)
|
static void test_qemu_strtoul_max(void)
|
||||||
@ -1528,6 +1564,15 @@ static void test_qemu_strtoi64_hex(void)
|
|||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0x123);
|
g_assert_cmpint(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
g_assert(endptr == str + strlen(str));
|
||||||
|
|
||||||
|
str = "0x";
|
||||||
|
endptr = &f;
|
||||||
|
res = 999;
|
||||||
|
err = qemu_strtoi64(str, &endptr, 16, &res);
|
||||||
|
|
||||||
|
g_assert_cmpint(err, ==, 0);
|
||||||
|
g_assert_cmpint(res, ==, 0);
|
||||||
|
g_assert(endptr == str + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_qemu_strtoi64_max(void)
|
static void test_qemu_strtoi64_max(void)
|
||||||
@ -1815,6 +1860,15 @@ static void test_qemu_strtou64_hex(void)
|
|||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmphex(res, ==, 0x123);
|
g_assert_cmphex(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
g_assert(endptr == str + strlen(str));
|
||||||
|
|
||||||
|
str = "0x";
|
||||||
|
endptr = &f;
|
||||||
|
res = 999;
|
||||||
|
err = qemu_strtou64(str, &endptr, 16, &res);
|
||||||
|
|
||||||
|
g_assert_cmpint(err, ==, 0);
|
||||||
|
g_assert_cmphex(res, ==, 0);
|
||||||
|
g_assert(endptr == str + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_qemu_strtou64_max(void)
|
static void test_qemu_strtou64_max(void)
|
||||||
|
@ -396,9 +396,22 @@ int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result)
|
|||||||
* Helper function for error checking after strtol() and the like
|
* Helper function for error checking after strtol() and the like
|
||||||
*/
|
*/
|
||||||
static int check_strtox_error(const char *nptr, char *ep,
|
static int check_strtox_error(const char *nptr, char *ep,
|
||||||
const char **endptr, int libc_errno)
|
const char **endptr, bool check_zero,
|
||||||
|
int libc_errno)
|
||||||
{
|
{
|
||||||
assert(ep >= nptr);
|
assert(ep >= nptr);
|
||||||
|
|
||||||
|
/* Windows has a bug in that it fails to parse 0 from "0x" in base 16 */
|
||||||
|
if (check_zero && ep == nptr && libc_errno == 0) {
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (strtol(nptr, &tmp, 10) == 0 && errno == 0 &&
|
||||||
|
(*tmp == 'x' || *tmp == 'X')) {
|
||||||
|
ep = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (endptr) {
|
if (endptr) {
|
||||||
*endptr = ep;
|
*endptr = ep;
|
||||||
}
|
}
|
||||||
@ -465,7 +478,7 @@ int qemu_strtoi(const char *nptr, const char **endptr, int base,
|
|||||||
} else {
|
} else {
|
||||||
*result = lresult;
|
*result = lresult;
|
||||||
}
|
}
|
||||||
return check_strtox_error(nptr, ep, endptr, errno);
|
return check_strtox_error(nptr, ep, endptr, lresult == 0, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -524,7 +537,7 @@ int qemu_strtoui(const char *nptr, const char **endptr, int base,
|
|||||||
*result = lresult;
|
*result = lresult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return check_strtox_error(nptr, ep, endptr, errno);
|
return check_strtox_error(nptr, ep, endptr, lresult == 0, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -566,7 +579,7 @@ int qemu_strtol(const char *nptr, const char **endptr, int base,
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*result = strtol(nptr, &ep, base);
|
*result = strtol(nptr, &ep, base);
|
||||||
return check_strtox_error(nptr, ep, endptr, errno);
|
return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -613,7 +626,7 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base,
|
|||||||
if (errno == ERANGE) {
|
if (errno == ERANGE) {
|
||||||
*result = -1;
|
*result = -1;
|
||||||
}
|
}
|
||||||
return check_strtox_error(nptr, ep, endptr, errno);
|
return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -639,7 +652,7 @@ int qemu_strtoi64(const char *nptr, const char **endptr, int base,
|
|||||||
QEMU_BUILD_BUG_ON(sizeof(int64_t) != sizeof(long long));
|
QEMU_BUILD_BUG_ON(sizeof(int64_t) != sizeof(long long));
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*result = strtoll(nptr, &ep, base);
|
*result = strtoll(nptr, &ep, base);
|
||||||
return check_strtox_error(nptr, ep, endptr, errno);
|
return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -668,7 +681,7 @@ int qemu_strtou64(const char *nptr, const char **endptr, int base,
|
|||||||
if (errno == ERANGE) {
|
if (errno == ERANGE) {
|
||||||
*result = -1;
|
*result = -1;
|
||||||
}
|
}
|
||||||
return check_strtox_error(nptr, ep, endptr, errno);
|
return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -708,7 +721,7 @@ int qemu_strtod(const char *nptr, const char **endptr, double *result)
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*result = strtod(nptr, &ep);
|
*result = strtod(nptr, &ep);
|
||||||
return check_strtox_error(nptr, ep, endptr, errno);
|
return check_strtox_error(nptr, ep, endptr, false, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user