[PATCH 5/6] parse-options: add precision handling for OPTION_BITOP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Similar to 09705696f7 (parse-options: introduce precision handling for
`OPTION_INTEGER`, 2025-04-17) support value variables of different sizes
for OPTION_BITOP.  Do that by requiring their "precision" to be set,
casting their "value" pointer accordingly and checking whether the value
fits.

Checking "defval" has the side-effect of also requiring PARSE_OPT_NOARG.
This is sensible, as OPTION_BITOP doesn't handle any arguments, so we
take this unintended benefit.

Don't check "extra", though, as its value is only used to clear bits, so
cannot lead to an overflow.  Not checking continues to allow e.g., using
-1 to clear all bits even if the value variable has a narrower type than
intptr_t.

Signed-off-by: René Scharfe <l.s.r@xxxxxx>
---
 parse-options.c | 10 +++++++---
 parse-options.h |  1 +
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/parse-options.c b/parse-options.c
index 6bd7158806..0dc9b0324a 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -156,11 +156,14 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
 	}
 
 	case OPTION_BITOP:
+	{
+		intmax_t value = get_int_value(opt);
 		if (unset)
 			BUG("BITOP can't have unset form");
-		*(int *)opt->value &= ~opt->extra;
-		*(int *)opt->value |= opt->defval;
-		return 0;
+		value &= ~opt->extra;
+		value |= opt->defval;
+		return set_int_value(opt, flags, value);
+	}
 
 	case OPTION_COUNTUP:
 		if (*(int *)opt->value < 0)
@@ -626,6 +629,7 @@ static void parse_options_check(const struct option *opts)
 		case OPTION_SET_INT:
 		case OPTION_BIT:
 		case OPTION_NEGBIT:
+		case OPTION_BITOP:
 			if (!signed_int_fits(opts->defval, opts->precision))
 				optbug(opts, "has invalid defval");
 			/* fallthru */
diff --git a/parse-options.h b/parse-options.h
index 076f88b384..8bdf469ae9 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -240,6 +240,7 @@ struct option {
 	.short_name = (s), \
 	.long_name = (l), \
 	.value = (v), \
+	.precision = sizeof(*v), \
 	.help = (h), \
 	.flags = PARSE_OPT_NOARG|PARSE_OPT_NONEG, \
 	.defval = (set), \
-- 
2.50.0





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux