]> git.ipfire.org Git - thirdparty/git.git/commitdiff
parse-options: add precision handling for OPTION_BITOP
authorRené Scharfe <l.s.r@web.de>
Wed, 9 Jul 2025 09:46:20 +0000 (11:46 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 9 Jul 2025 15:39:46 +0000 (08:39 -0700)
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.

Check if "devfal" fits into an integer variable with the given
"precision", but don't check "extra", 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@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
parse-options.c
parse-options.h

index ba89dc4d098d60cdaeb6ed7e5515bcbe38593bcd..a813511b1bcb68c348cc840b2f26ef98544dcecd 100644 (file)
@@ -167,11 +167,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, flags);
                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)
@@ -647,12 +650,12 @@ 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 */
                case OPTION_COUNTUP:
                case OPTION_NUMBER:
-               case OPTION_BITOP:
                        if ((opts->flags & PARSE_OPT_OPTARG) ||
                            !(opts->flags & PARSE_OPT_NOARG))
                                optbug(opts, "should not accept an argument");
index 076f88b3841da36a6c0aa53f9d4135e212e80c24..8bdf469ae9b29a5bd0b6f4b56e927735036ee308 100644 (file)
@@ -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), \