mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-05-14 20:28:08 +02:00
util: fix xatou_base for values > UINT_MAX
The check `(long)v < 0` only catches values >= LONG_MAX when cast to signed long. On 64-bit systems where sizeof(long) == 8, values between UINT_MAX+1 and LONG_MAX pass this check but silently truncate when assigned to the unsigned int output parameter. Use `v > UINT_MAX` for a correct range check. Assisted-by: Claude:claude-opus-4-6 Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/388>
This commit is contained in:
parent
bbcc808b1a
commit
bacd62cae0
2 changed files with 67 additions and 1 deletions
|
|
@ -658,4 +658,70 @@ MUNIT_TEST(test_strv_from_mem)
|
|||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_xatou)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
munit_assert_true(xatou("0", &val));
|
||||
munit_assert_uint(val, ==, 0);
|
||||
|
||||
munit_assert_true(xatou("1", &val));
|
||||
munit_assert_uint(val, ==, 1);
|
||||
|
||||
munit_assert_true(xatou("123", &val));
|
||||
munit_assert_uint(val, ==, 123);
|
||||
|
||||
/* UINT_MAX is the upper boundary, must succeed */
|
||||
munit_assert_true(xatou("4294967295", &val));
|
||||
munit_assert_uint(val, ==, UINT_MAX);
|
||||
|
||||
/* UINT_MAX + 1 must fail */
|
||||
munit_assert_false(xatou("4294967296", &val));
|
||||
|
||||
/* Another random value in the range UINT_MAX < val < LONG_MAX */
|
||||
munit_assert_false(xatou("8589934592", &val));
|
||||
|
||||
/* LONG_MAX as string - must fail */
|
||||
munit_assert_false(xatou("9223372036854775807", &val));
|
||||
|
||||
/* Overflow beyond ULONG_MAX - strtoul sets errno, must fail */
|
||||
munit_assert_false(xatou("18446744073709551616", &val));
|
||||
|
||||
/* negative numbers: strtoul wraps "-1" to ULONG_MAX without
|
||||
* setting errno, but v > UINT_MAX catches it */
|
||||
munit_assert_false(xatou("-1", &val));
|
||||
|
||||
/* invalid strings */
|
||||
munit_assert_false(xatou("", &val));
|
||||
munit_assert_false(xatou("abc", &val));
|
||||
munit_assert_false(xatou("123abc", &val));
|
||||
munit_assert_false(xatou("12 34", &val));
|
||||
|
||||
/* hex via xatou_base */
|
||||
munit_assert_true(xatou_base("ff", &val, 16));
|
||||
munit_assert_uint(val, ==, 0xff);
|
||||
|
||||
munit_assert_true(xatou_base("0xff", &val, 16));
|
||||
munit_assert_uint(val, ==, 0xff);
|
||||
|
||||
munit_assert_true(xatou_base("FFFFFFFF", &val, 16));
|
||||
munit_assert_uint(val, ==, UINT_MAX);
|
||||
|
||||
/* hex UINT_MAX + 1 */
|
||||
munit_assert_false(xatou_base("100000000", &val, 16));
|
||||
|
||||
/* octal */
|
||||
munit_assert_true(xatou_base("77", &val, 8));
|
||||
munit_assert_uint(val, ==, 077);
|
||||
|
||||
munit_assert_true(xatou_base("37777777777", &val, 8));
|
||||
munit_assert_uint(val, ==, UINT_MAX);
|
||||
|
||||
/* octal UINT_MAX + 1 */
|
||||
munit_assert_false(xatou_base("40000000000", &val, 8));
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ xatou_base(const char *str, unsigned int *val, int base)
|
|||
if (*str != '\0' && *endptr != '\0')
|
||||
return false;
|
||||
|
||||
if ((long)v < 0)
|
||||
if (v > UINT_MAX)
|
||||
return false;
|
||||
|
||||
*val = v;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue