zsh5.0.8に存在するローカル変数のパーサバグ


概要

zsh5.0.8には local a=()a=という関数 だとパースしてしまうバグがあります。後ろに続くリテラル次第でセグフォを起こします。

※ メーリングリストでバグ報告済みです。

バグ再現方法

以下のファイルを作成します。

funcs.zsh
func1() {
    a=( )
    b=false
    echo "a in func1 length: ${#a[@]}"
}
func2() {
    local a=( )
    local b=false
    echo "a in func2 length: ${#a[@]}"
}
func3() {
    a=()
    b=false
    echo "a in func3 length: ${#a[@]}"
}
func4() {
    local a=()
    local b=false
    echo "a in func4 length: ${#a[@]}"
}

検証するときはzshセッション内であってもzshを新たに起動してください。最後にセグフォで死んだときのエラーメッセージが見れるようになるからです。

検証
example@local:~$ zsh
example@local:~$ zsh --version
zsh 5.0.8 (x86_64-apple-darwin14.3.0)
example@local:~$ source funcs.zsh
example@local:~$ func1
a in func1 length: 0
example@local:~$ func2
func2:1: unknown file attribute:
example@local:~$ func3
a in func3 length: 0
example@local:~$ func4
a in func4 length: 0
[1]    35208 segmentation fault  zsh

func4が落ちるならfunc2のようにスペース開ければ回避出来ないかなぁと考えたのですが、これはこれでダメみたいですね。

後から気づいたので追記します。どうやら空配列かどうかに限らず、localをつけて配列を宣言すること自体が出来ない模様です。

バグ回避方法

宣言と代入を別にすることで回避出来るようです。

local a
a=()

関連するツイート

環境によってはセグフォまではいかないみたいです。