Skip to content
This repository was archived by the owner on Nov 15, 2025. It is now read-only.

Commit ce51632

Browse files
committed
basic/parse-util: add safe_atoux64()
1 parent 1b87e27 commit ce51632

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

src/basic/parse-util.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ int safe_atoi(const char *s, int *ret_i) {
395395
return 0;
396396
}
397397

398-
int safe_atollu(const char *s, long long unsigned *ret_llu) {
398+
int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) {
399399
char *x = NULL;
400400
unsigned long long l;
401401

@@ -404,7 +404,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
404404
s += strspn(s, WHITESPACE);
405405

406406
errno = 0;
407-
l = strtoull(s, &x, 0);
407+
l = strtoull(s, &x, base);
408408
if (errno > 0)
409409
return -errno;
410410
if (!x || x == s || *x != 0)

src/basic/parse-util.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ static inline int safe_atou(const char *s, unsigned *ret_u) {
2828
}
2929

3030
int safe_atoi(const char *s, int *ret_i);
31-
int safe_atollu(const char *s, unsigned long long *ret_u);
3231
int safe_atolli(const char *s, long long int *ret_i);
3332

3433
int safe_atou8(const char *s, uint8_t *ret);
@@ -59,6 +58,12 @@ static inline int safe_atoi32(const char *s, int32_t *ret_i) {
5958
return safe_atoi(s, (int*) ret_i);
6059
}
6160

61+
int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu);
62+
63+
static inline int safe_atollu(const char *s, long long unsigned *ret_llu) {
64+
return safe_atollu_full(s, 0, ret_llu);
65+
}
66+
6267
static inline int safe_atou64(const char *s, uint64_t *ret_u) {
6368
assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
6469
return safe_atollu(s, (unsigned long long*) ret_u);
@@ -69,6 +74,11 @@ static inline int safe_atoi64(const char *s, int64_t *ret_i) {
6974
return safe_atolli(s, (long long int*) ret_i);
7075
}
7176

77+
static inline int safe_atoux64(const char *s, uint64_t *ret) {
78+
assert_cc(sizeof(int64_t) == sizeof(long long unsigned));
79+
return safe_atollu_full(s, 16, (long long unsigned*) ret);
80+
}
81+
7282
#if LONG_MAX == INT_MAX
7383
static inline int safe_atolu(const char *s, unsigned long *ret_u) {
7484
assert_cc(sizeof(unsigned long) == sizeof(unsigned));

src/test/test-parse-util.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,44 @@ static void test_safe_atoi64(void) {
561561
assert_se(r == -EINVAL);
562562
}
563563

564+
static void test_safe_atoux64(void) {
565+
int r;
566+
uint64_t l;
567+
568+
r = safe_atoux64("12345", &l);
569+
assert_se(r == 0);
570+
assert_se(l == 0x12345);
571+
572+
r = safe_atoux64(" 12345", &l);
573+
assert_se(r == 0);
574+
assert_se(l == 0x12345);
575+
576+
r = safe_atoux64("0x12345", &l);
577+
assert_se(r == 0);
578+
assert_se(l == 0x12345);
579+
580+
r = safe_atoux64("18446744073709551617", &l);
581+
assert_se(r == -ERANGE);
582+
583+
r = safe_atoux64("-1", &l);
584+
assert_se(r == -ERANGE);
585+
586+
r = safe_atoux64(" -1", &l);
587+
assert_se(r == -ERANGE);
588+
589+
r = safe_atoux64("junk", &l);
590+
assert_se(r == -EINVAL);
591+
592+
r = safe_atoux64("123x", &l);
593+
assert_se(r == -EINVAL);
594+
595+
r = safe_atoux64("12.3", &l);
596+
assert_se(r == -EINVAL);
597+
598+
r = safe_atoux64("", &l);
599+
assert_se(r == -EINVAL);
600+
}
601+
564602
static void test_safe_atod(void) {
565603
int r;
566604
double d;
@@ -838,6 +876,7 @@ int main(int argc, char *argv[]) {
838876
test_safe_atoux16();
839877
test_safe_atou64();
840878
test_safe_atoi64();
879+
test_safe_atoux64();
841880
test_safe_atod();
842881
test_parse_percent();
843882
test_parse_percent_unbounded();

0 commit comments

Comments
 (0)