[PATCH] Fix math evaluation error in zargs when using --max-args=X syntax

"Bostjan Hribar" <[email protected]>
Newsgroups gmane.comp.shells.zsh.devel
Message-ID <[email protected]>
Hello Zsh Workers,

I have identified a math evaluation bug in the autoloaded `zargs` contribution function when parsing long options with an embedded equals sign delimiter (e.g., `--max-args=200`), along with a proposed code-level patch.

Steps to reproduce:
$ zsh -f
$ autoload -U zargs
$ zargs --max-args=200 -- some_command ...

Actual behavior:
zargs:230: bad math expression: operand expected at `=200'
zargs:236: bad math expression: operand expected at `=200'
zargs: argument list too long

Analysis:
The function uses `zparseopts` to populate the `n`, `s`, `l`, and `P` arrays:
zparseopts -a opts -D -- ... -max-args:=n n:=n ...

When passing `--max-args=200`, `zparseopts` populates the `n` array with two distinct elements:
n[1] -> "--max-args"
n[2] -> "=200"

The current variable assignment mechanism on line 230 reads:
n=${${n##-(n|-max-args(=|))}:-$[ARGC+c]}

Because `n` is an array, Zsh applies the prefix truncation `##` to each element individually. Element 1 matches and is stripped. Element 2 (`=200`) fails the prefix match (as it does not start with `-n` or `-max-args`) and remains untouched. 

When the array is implicitly joined back into a scalar string, it results in the literal string `" =200"`. This raw equals sign is preserved downstream, causing the arithmetic evaluation block `(( end > n && ( end = n ) ))` to crash.

Proposed Patch:
Target the last array slice element explicitly and strip any potential leading equals operator (`[-1]#=`). This bypasses the need for a complex prefix match over the entire array, handles spaces or equals signs gracefully, and safely preserves the original fallback defaults.

--- functions/zargs.orig
+++ functions/zargs
@@ -226,7 +226,7 @@
     fi
 fi

-n=${${n##-(n|-max-args(=|))}:-$[ARGC+c]}
+n=${${n[-1]#=}:-$[ARGC+c]}
 if (( n <= 0 ))
 then
     print -u2 'zargs: value for max-args must be >= 1'
@@ -240,21 +240,21 @@
     return 1
 fi

-s=${${s##-(s|-max-chars(=|))}:-20480}
+s=${${s[-1]#=}:-20480}
 if (( s <= 0 ))
 then
     print -u2 'zargs: value for max-chars must be >= 1'
     return 1
 fi

-l=${${${l##*-(l|L|-max-lines(=|))}[-1]}:-${${l[1]:+1}:-$ARGC}}
+l=${${l[-1]#=}:-${${l[1]:+1}:-$ARGC}}
 if (( l <= 0 ))
 then
     print -u2 'zargs: value for max-lines must be >= 1'
     return 1
 fi

-P=${${P##-(P|-max-procs(=|))}:-1}
+P=${${P[-1]#=}:-1}
 if (( P < 0 ))
 then
     print -u2 'zargs: value for max-procs must be >= 0'

Environment Details:
- Zsh Version: zsh 5.9 (x86_64-apple-darwin23.6.0 via Homebrew Cellar)
- Operating System: macOS 15.7.5 (Build 24G624)
- Kernel Version: Darwin 24.6.0 (RELEASE_X86_64)

Thank you,
Bostjan H
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.