Hello, I have the following piece of code involving the use of the zsh/param/private module that segfaults as seen below ``` ➜ ~ zsh -f -x -c 'zmodload zsh/param/private function _TEST { private arg for arg in "${@}"; do case "${arg}" in test1=*) private test1="${arg#*=}" ;; test2=*) private test2="${arg#*=}" ;; esac done echo "test1=${test1}" echo "test2=${test2}" } _TEST test1="" test2=""' +zsh:1> zmodload zsh/param/private +zsh:20> _TEST 'test1=' 'test2=' +_TEST:1> private arg +_TEST:2> arg=test1= +_TEST:3> case test1= (test1=*) +_TEST:5> private 'test1=' +_TEST:2> arg=test2= +_TEST:3> case test2= (test1=*) +_TEST:3> case test2= (test2=*) +_TEST:9> private 'test2=' [1] 3152586 segmentation fault (core dumped) zsh -f -x -c ``` It's happening on the latest version of zsh which I installed using brew on Ubuntu 20.04 (was using 5.8 installed via apt but uninstalled to check if the issue was still occurring on 5.9) ``` ➜ ~ zsh --version zsh 5.9 (x86_64-pc-linux-gnu) ➜ ~ brew info zsh ==> zsh: stable 5.9 (bottled), HEAD UNIX shell (command interpreter) https://www.zsh.org/ /home/linuxbrew/.linuxbrew/Cellar/zsh/5.9 (1,578 files, 14.9MB) * Poured from bottle using the formulae.brew.sh API on 2023-07-19 at 22:38:08 From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/zsh.rb License: MIT-Modern-Variant ==> Dependencies Build: texinfo ✘ Required: ncurses ✔, pcre ✔, gcc ✔, glibc ✔ ==> Options --HEAD Install HEAD version ==> Analytics install: 7,575 (30 days), 28,511 (90 days), 38,178 (365 days) install-on-request: 7,409 (30 days), 27,934 (90 days), 37,383 (365 days) build-error: 0 (30 days) ``` The segfault occurs regardless of whether `test1` and `test2` are empty or non-empty strings as seen below ``` ➜ ~ zsh -f -x -c 'zmodload zsh/param/private function _TEST { private arg for arg in "${@}"; do case "${arg}" in test1=*) private test1="${arg#*=}" ;; test2=*) private test2="${arg#*=}" ;; esac done echo "test1=${test1}" echo "test2=${test2}" } _TEST test1="test3" test2="test4"' +zsh:1> zmodload zsh/param/private +zsh:20> _TEST 'test1=test3' 'test2=test4' +_TEST:1> private arg +_TEST:2> arg=test1=test3 +_TEST:3> case test1=test3 (test1=*) +_TEST:5> private 'test1=test3' +_TEST:2> arg=test2=test4 +_TEST:3> case test2=test4 (test1=*) +_TEST:3> case test2=test4 (test2=*) +_TEST:9> private 'test2=test4' [1] 3155156 segmentation fault (core dumped) zsh -f -x -c ``` But strangely enough, does not happen when `test2` is omitted from the code altogether as seen below ``` ➜ ~ zsh -f -x -c 'zmodload zsh/param/private function _TEST { private arg for arg in "${@}"; do case "${arg}" in test1=*) private test1="${arg#*=}" ;; esac done echo "test1=${test1}" } _TEST test1=""' +zsh:1> zmodload zsh/param/private +zsh:15> _TEST 'test1=' +_TEST:1> private arg +_TEST:2> arg=test1= +_TEST:3> case test1= (test1=*) +_TEST:5> private 'test1=' +_TEST:10> echo 'test1=' test1= ``` It does, however, happen for 2 or more cases and somehow gets to the very end before segfault-ing instead of doing so by the second case ``` ➜ ~ zsh -f -x -c 'zmodload zsh/param/private function _TEST { private arg for arg in "${@}"; do case "${arg}" in test1=*) private test1="${arg#*=}" ;; test2=*) private test2="${arg#*=}" ;; test3=*) private test3="${arg#*=}" ;; esac done echo "test1=${test1}" echo "test2=${test2}" <.... +zsh:1> zmodload zsh/param/private +zsh:25> _TEST 'test1=' 'test2=' 'test3=' +_TEST:1> private arg +_TEST:2> arg=test1= +_TEST:3> case test1= (test1=*) +_TEST:5> private 'test1=' +_TEST:2> arg=test2= +_TEST:3> case test2= (test1=*) +_TEST:3> case test2= (test2=*) +_TEST:9> private 'test2=' +_TEST:2> arg=test3= +_TEST:3> case test3= (test1=*) +_TEST:3> case test3= (test2=*) +_TEST:3> case test3= (test3=*) +_TEST:13> private 'test3=' [1] 3154406 segmentation fault (core dumped) zsh -f -x -c ``` One easy workaround is to declare the `private` variables outside the for loop as seen below ``` ➜ ~ zsh -f -x -c 'zmodload zsh/param/private function _TEST { private arg test1 test2 for arg in "${@}"; do case "${arg}" in test1=*) test1="${arg#*=}" ;; test2=*) test2="${arg#*=}" ;; esac done echo "test1=${test1}" echo "test2=${test2}" } _TEST test1="" test2=""' +zsh:1> zmodload zsh/param/private +zsh:20> _TEST 'test1=' 'test2=' +_TEST:1> private arg test1 test2 +_TEST:2> arg=test1= +_TEST:3> case test1= (test1=*) +_TEST:5> test1='' +_TEST:2> arg=test2= +_TEST:3> case test2= (test1=*) +_TEST:3> case test2= (test2=*) +_TEST:9> test2='' +_TEST:14> echo 'test1=' test1= +_TEST:15> echo 'test2=' test2= ``` but I still think it's a bug because why would the single case scenario work but not the multi-case scenario? I also tried `local -P` instead of `private` but it yielded the same segfault ``` ➜ ~ zsh -f -x -c 'zmodload zsh/param/private function _TEST { local -P arg for arg in "${@}"; do case "${arg}" in test1=*) local -P test1="${arg#*=}" ;; test2=*) local -P test2="${arg#*=}" ;; esac done echo "test1=${test1}" echo "test2=${test2}" } _TEST test1="" test2=""' +zsh:1> zmodload zsh/param/private +zsh:20> _TEST 'test1=' 'test2=' +_TEST:1> local -P arg +_TEST:2> arg=test1= +_TEST:3> case test1= (test1=*) +_TEST:5> local -P test1='' +_TEST:2> arg=test2= +_TEST:3> case test2= (test1=*) +_TEST:3> case test2= (test2=*) +_TEST:9> local -P test2='' [1] 3158070 segmentation fault (core dumped) zsh -f -x -c ``` The `local` keyword works fine but it obviously doesn't limit the scope of the variables as much as `private` ``` ➜ ~ zsh -f -x -c 'zmodload zsh/param/private function _TEST { local arg for arg in "${@}"; do case "${arg}" in test1=*) local test1="${arg#*=}" ;; test2=*) local test2="${arg#*=}" ;; esac done echo "test1=${test1}" echo "test2=${test2}" } _TEST test1="" test2=""' +zsh:1> zmodload zsh/param/private +zsh:20> _TEST 'test1=' 'test2=' +_TEST:1> local arg +_TEST:2> arg=test1= +_TEST:3> case test1= (test1=*) +_TEST:5> local test1='' +_TEST:2> arg=test2= +_TEST:3> case test2= (test1=*) +_TEST:3> case test2= (test2=*) +_TEST:9> local test2='' +_TEST:14> echo 'test1=' test1= +_TEST:15> echo 'test2=' test2= ``` I don't know if this bug has been reported before, so please do reply to this email if it is already being worked on (it would also be nice to know if it was a new find). Otherwise, I hope to see this fixed some time in the future. Best regards, TAN Wei Xin, Alez