Git fork

parse-options: add precision handling for OPTION_BITOP

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>

authored by

René Scharfe and committed by
Junio C Hamano
1d918bf2 feeebbf1

+8 -4
+7 -4
parse-options.c
··· 167 167 } 168 168 169 169 case OPTION_BITOP: 170 + { 171 + intmax_t value = get_int_value(opt, flags); 170 172 if (unset) 171 173 BUG("BITOP can't have unset form"); 172 - *(int *)opt->value &= ~opt->extra; 173 - *(int *)opt->value |= opt->defval; 174 - return 0; 174 + value &= ~opt->extra; 175 + value |= opt->defval; 176 + return set_int_value(opt, flags, value); 177 + } 175 178 176 179 case OPTION_COUNTUP: 177 180 if (*(int *)opt->value < 0) ··· 647 650 case OPTION_SET_INT: 648 651 case OPTION_BIT: 649 652 case OPTION_NEGBIT: 653 + case OPTION_BITOP: 650 654 if (!signed_int_fits(opts->defval, opts->precision)) 651 655 optbug(opts, "has invalid defval"); 652 656 /* fallthru */ 653 657 case OPTION_COUNTUP: 654 658 case OPTION_NUMBER: 655 - case OPTION_BITOP: 656 659 if ((opts->flags & PARSE_OPT_OPTARG) || 657 660 !(opts->flags & PARSE_OPT_NOARG)) 658 661 optbug(opts, "should not accept an argument");
+1
parse-options.h
··· 240 240 .short_name = (s), \ 241 241 .long_name = (l), \ 242 242 .value = (v), \ 243 + .precision = sizeof(*v), \ 243 244 .help = (h), \ 244 245 .flags = PARSE_OPT_NOARG|PARSE_OPT_NONEG, \ 245 246 .defval = (set), \