You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
php_getopt() does not clear *optarg for long options with optional argument when value is absent — --ini regression in 8.5 #21901
In PHP 8.5 the --ini CLI option was changed from no_argument to optional_argument to support the new --ini=diff subcommand. As a side effect, --ini (without a value) now fails with Unknown argument for --ini whenever it is preceded on the command line by another option that takes a required argument.
Reproducer (PHP 8.5):
$ php --ini # OK
$ php -n --ini # OK (-n takes no argument)
$ php -c /etc/php.ini --ini # FAIL: Unknown argument for --ini
$ php -d foo=bar --ini # FAIL: Unknown argument for --ini
$ php --ini -c /etc/php.ini # OK (workaround: reorder)
The same commands work correctly in PHP 8.4 and earlier.
Expected behavior:
--ini without a value should be treated identically regardless of its position on the command line, equivalent to --ini=.
Root cause:
In main/getopt.c, php_getopt() does not reset *optarg between calls. When a long option is declared with need_param == 2 (optional) and is supplied without =value, the function falls through without assigning *optarg, leaving it pointing at the value consumed by the previous option (e.g. the path passed to -c, or the assignment passed to -d). The CLI SAPI then interprets that stale value as the --ini subcommand, fails to match it against "" or "diff", and emits the error.
The bug existed before 8.5 but was never observable because no long option used optional_argument. The introduction of --ini=diff (and the corresponding flip of --ini to optional_argument) exposed it.
Affected versions: 8.5.0 and later (any build with --ini=diff support).
Proposed Patch
The simplest and most defensive fix is to clear *optarg at the top of php_getopt() so that callers never observe a stale pointer from a previous invocation, regardless of which code path is taken later.
Activity
Fix stale getopt() optional value in CLI