Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
[PATCH] Fix math evaluation error in zargs when using --max-args=X syntax
- X-seq: zsh-workers 54521
- From: "Bostjan Hribar" <hribcek@xxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: [PATCH] Fix math evaluation error in zargs when using --max-args=X syntax
- Date: Tue, 12 May 2026 01:59:07 +0000
- Archived-at: <https://zsh.org/workers/54521>
- List-id: <zsh-workers.zsh.org>
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
Messages sorted by:
Reverse Date,
Date,
Thread,
Author