aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2026-06-12 13:55:27 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2026-06-14 01:01:55 +0000
commit4249a9bc098dd9e32105a2965e76abd702de4d4a (patch)
tree8fc34dcbf043f7bc74c0f3671f23b12a33dcf774
parent69e20977a468c9e570ee896ed7cf04969e86756d (diff)
rtld parse_integer(): support binary, octal, and hex C notations
Reviewed by: des, dim Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D57549
-rw-r--r--libexec/rtld-elf/rtld.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 29984e40b574..a72726684f0f 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -6537,27 +6537,52 @@ parse_args(char *argv[], int argc, bool *use_pathp, int *fdp,
static int
parse_integer(const char *str)
{
- static const int RADIX = 10; /* XXXJA: possibly support hex? */
+ int radix;
const char *orig;
- int n;
+ int n, val;
char c;
+ if (str[0] == '0') {
+ if (str[1] == 'x') {
+ str += 2;
+ radix = 16;
+ } else if (str[1] == 'b') {
+ str += 2;
+ radix = 2;
+ } else {
+ str += 1;
+ radix = 8;
+ }
+ } else {
+ radix = 10;
+ }
orig = str;
n = 0;
for (c = *str; c != '\0'; c = *++str) {
- if (c < '0' || c > '9')
+ if (c >= '0' && c <= '9')
+ val = c - '0';
+ else if (c >= 'a' && c <= 'f')
+ val = c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ val = c - 'A' + 10;
+ else
+ return (-1);
+ if (val >= radix)
return (-1);
- if (n > INT_MAX / RADIX)
+ if (n > INT_MAX / radix)
return (-1);
- n *= RADIX;
- if (n > INT_MAX - (c - '0'))
+ n *= radix;
+ if (n > INT_MAX - val)
return (-1);
- n += c - '0';
+ n += val;
}
- /* Make sure we actually parsed something. */
- if (str == orig)
+ /*
+ * Make sure we actually parsed something.
+ * Allow for lone '0'.
+ */
+ if (str == orig && radix != 8)
return (-1);
return (n);
}