zsh-workers
 help / color / mirror / code / Atom feed
* Segfault while using zsh/param/private module
@ 2023-07-19 22:23 Alezender Tan
  2023-07-20  4:19 ` Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Alezender Tan @ 2023-07-19 22:23 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 7130 bytes --]

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

[-- Attachment #2: Type: text/html, Size: 9592 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Segfault while using zsh/param/private module
  2023-07-19 22:23 Segfault while using zsh/param/private module Alezender Tan
@ 2023-07-20  4:19 ` Bart Schaefer
  2023-07-20  4:22   ` Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Bart Schaefer @ 2023-07-20  4:19 UTC (permalink / raw)
  To: Alezender Tan; +Cc: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 433 bytes --]

On Wed, Jul 19, 2023 at 3:24 PM Alezender Tan <
tan.wei.xin.alezender+zsh@gmail.com> wrote:

> I have the following piece of code involving the use of the
> zsh/param/private module that segfaults as seen below
>

I'm not able to reproduce this using git HEAD on either Ubuntu or MacOS,
and "valgrind" on the examples provided does not report any memory error.

Optimizer problem?  I'm compiling with debugging symbols.

[-- Attachment #2: Type: text/html, Size: 802 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Segfault while using zsh/param/private module
  2023-07-20  4:19 ` Bart Schaefer
@ 2023-07-20  4:22   ` Bart Schaefer
  0 siblings, 0 replies; 3+ messages in thread
From: Bart Schaefer @ 2023-07-20  4:22 UTC (permalink / raw)
  To: Alezender Tan; +Cc: zsh-workers

On Wed, Jul 19, 2023 at 9:19 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Wed, Jul 19, 2023 at 3:24 PM Alezender Tan <tan.wei.xin.alezender+zsh@gmail.com> wrote:
>>
>> I have the following piece of code involving the use of the zsh/param/private module that segfaults as seen below
>
>
> I'm not able to reproduce this using git HEAD

Possibly fixed in workers/50363, git commit 285b6c25 ?

50363: avoid use of heap memory that depends on parameter scoping


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-07-20  4:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-19 22:23 Segfault while using zsh/param/private module Alezender Tan
2023-07-20  4:19 ` Bart Schaefer
2023-07-20  4:22   ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).