Page MenuHomeFreeBSD

D57549.id179669.diff
No OneTemporary

D57549.id179669.diff

diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -6537,27 +6537,59 @@
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')
+ /* Letters are after digits in ASCII */
+ if (c < '0')
return (-1);
+ if (radix <= 10) {
+ val = c - '0';
+ if (val >= radix)
+ return (-1);
+ } else /* radix == 16 */ {
+ 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 (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);
}
diff --git a/libexec/rtld-elf/tests/Makefile b/libexec/rtld-elf/tests/Makefile
--- a/libexec/rtld-elf/tests/Makefile
+++ b/libexec/rtld-elf/tests/Makefile
@@ -1,3 +1,5 @@
+#include <src.opts.mk>
+
SUBDIR+= libpythagoras libdeep libval libval2 target
TESTS_SUBDIRS+= rtld_deepbind
@@ -16,6 +18,14 @@
ATF_TESTS_C+= dlopen_test
ATF_TESTS_C+= dlopen_hash_test
+ATF_TESTS_C+= parse_integer_test
+parse_integer_test.c: parse_integer_func.c
+CFLAGS.parse_integer_test.c+= -I${.OBJDIR}
+parse_integer_func.c: ${SRCTOP}/libexec/rtld-elf/rtld.c
+ sed -ne '/^parse_integer/,/^\}/p' ${SRCTOP}/libexec/rtld-elf/rtld.c \
+ >parse_integer_func.c
+CLEANFILES+= parse_integer_func.c
+
WARNS?= 3
.include <bsd.test.mk>
diff --git a/libexec/rtld-elf/tests/parse_integer_test.c b/libexec/rtld-elf/tests/parse_integer_test.c
new file mode 100644
--- /dev/null
+++ b/libexec/rtld-elf/tests/parse_integer_test.c
@@ -0,0 +1,35 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2026 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ */
+
+#include <limits.h>
+#include <atf-c.h>
+
+static int
+#include "parse_integer_func.c"
+
+ATF_TC_WITHOUT_HEAD(integers);
+ATF_TC_BODY(integers, tc)
+{
+ ATF_REQUIRE_EQ(parse_integer("0"), 0);
+ ATF_REQUIRE_EQ(parse_integer("10"), 10);
+ ATF_REQUIRE_EQ(parse_integer("10001"), 10001);
+ ATF_REQUIRE_EQ(parse_integer("0b101"), 0b101);
+ ATF_REQUIRE_EQ(parse_integer("0x10"), 0x10);
+ ATF_REQUIRE_EQ(parse_integer("020"), 020);
+ ATF_REQUIRE_EQ(parse_integer("090"), -1);
+ /* This test assumes some value for INT_MAX */
+ ATF_REQUIRE_EQ(parse_integer("1111111111111111111111111111"), -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, integers);
+ return (atf_no_error());
+}

File Metadata

Mime Type
text/plain
Expires
Thu, Aug 20, 5:38 PM (9 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37004798
Default Alt Text
D57549.id179669.diff (3 KB)

Event Timeline