mirror of
https://github.com/torvalds/linux.git
synced 2026-10-25 08:16:03 +01:00
kconfig: use unsigned integers for hex range checks
While 'hex' values should use the bounds of 64-bit unsigned integers, the
range values are treated as signed (checks use strtoll).
For example:
config HEX_RANGE
hex
range 0 0xfffffffffffffffe
default 0xffffffffffffffff
the default value should adjust down to the upper bound of
0xfffffffffffffffe, but since the check incorrectly parses both as
LLONG_MAX, the value stays at the out-of-range default of
0xffffffffffffffff.
To fix this, let's use a union of signed and unsigned integers to
represent both 'int' and 'hex' range values, then use both strtoll and
strtoull where appropriate.
Assisted-by: LLM
Signed-off-by: Julian Braha <julianbraha@gmail.com>
Reviewed-by: Nicolas Schier <n.schier@fritz.com>
Link: https://patch.msgid.link/20260915211508.291790-6-julianbraha@gmail.com
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
This commit is contained in:
parent
54f11924e4
commit
9b8719973e
|
|
@ -142,8 +142,15 @@ struct property *sym_get_range_prop(struct symbol *sym)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static long long sym_get_range_val(struct symbol *sym, int base)
|
||||
union range_value {
|
||||
long long s;
|
||||
unsigned long long u;
|
||||
};
|
||||
|
||||
static union range_value sym_get_range_val(struct symbol *sym, int base)
|
||||
{
|
||||
union range_value val;
|
||||
|
||||
sym_calc_value(sym);
|
||||
switch (sym->type) {
|
||||
case S_INT:
|
||||
|
|
@ -155,7 +162,12 @@ static long long sym_get_range_val(struct symbol *sym, int base)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
return strtoll(sym->curr.val, NULL, base);
|
||||
if (base == 10)
|
||||
val.s = strtoll(sym->curr.val, NULL, base);
|
||||
else
|
||||
/* HEX */
|
||||
val.u = strtoull(sym->curr.val, NULL, base);
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -168,7 +180,7 @@ static struct symbol *sym_get_near_range_bound(struct symbol *sym,
|
|||
struct property *prop;
|
||||
struct symbol *range_sym;
|
||||
int base;
|
||||
long long val, val2;
|
||||
union range_value val, val2;
|
||||
|
||||
switch (sym->type) {
|
||||
case S_INT:
|
||||
|
|
@ -183,13 +195,19 @@ static struct symbol *sym_get_near_range_bound(struct symbol *sym,
|
|||
prop = sym_get_range_prop(sym);
|
||||
if (!prop)
|
||||
return NULL;
|
||||
val = strtoll(value, NULL, base);
|
||||
val = sym_get_range_val(sym, base);
|
||||
range_sym = prop->expr->left.sym;
|
||||
val2 = sym_get_range_val(range_sym, base);
|
||||
if (val >= val2) {
|
||||
|
||||
if (base == 10 && val.s >= val2.s) {
|
||||
range_sym = prop->expr->right.sym;
|
||||
val2 = sym_get_range_val(range_sym, base);
|
||||
if (val <= val2)
|
||||
if (val.s <= val2.s)
|
||||
return NULL;
|
||||
} else if (base == 16 && val.u >= val2.u) {
|
||||
range_sym = prop->expr->right.sym;
|
||||
val2 = sym_get_range_val(range_sym, base);
|
||||
if (val.u <= val2.u)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -746,6 +764,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
|
|||
{
|
||||
struct property *prop;
|
||||
long long val;
|
||||
unsigned long long uval;
|
||||
|
||||
switch (sym->type) {
|
||||
case S_STRING:
|
||||
|
|
@ -759,8 +778,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
|
|||
if (!prop)
|
||||
return true;
|
||||
val = strtoll(str, NULL, 10);
|
||||
return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
|
||||
val <= sym_get_range_val(prop->expr->right.sym, 10);
|
||||
return val >= sym_get_range_val(prop->expr->left.sym, 10).s &&
|
||||
val <= sym_get_range_val(prop->expr->right.sym, 10).s;
|
||||
case S_HEX:
|
||||
if (!sym_string_valid(sym, str))
|
||||
return false;
|
||||
|
|
@ -769,9 +788,9 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
|
|||
prop = sym_get_range_prop(sym);
|
||||
if (!prop)
|
||||
return true;
|
||||
val = strtoll(str, NULL, 16);
|
||||
return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
|
||||
val <= sym_get_range_val(prop->expr->right.sym, 16);
|
||||
uval = strtoull(str, NULL, 16);
|
||||
return uval >= sym_get_range_val(prop->expr->left.sym, 16).u &&
|
||||
uval <= sym_get_range_val(prop->expr->right.sym, 16).u;
|
||||
case S_BOOLEAN:
|
||||
case S_TRISTATE:
|
||||
switch (str[0]) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ config NUM
|
|||
Kconfig resolves it to the constrained in-range value.
|
||||
The warning should report that adjustment.
|
||||
|
||||
config HEX_RANGE
|
||||
hex
|
||||
range 0 0xfffffffffffffffe
|
||||
default 0xffffffffffffffff
|
||||
|
||||
config DUP
|
||||
bool "DUP"
|
||||
depends on DEP
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@
|
|||
#
|
||||
# CONFIG_DEP is not set
|
||||
CONFIG_NUM=20
|
||||
CONFIG_HEX_RANGE=0xfffffffffffffffe
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user