概要
zsh5.0.8には local a=()
を a=
という関数 だとパースしてしまうバグがあります。後ろに続くリテラル次第でセグフォを起こします。
※ メーリングリストでバグ報告済みです。
バグ再現方法
以下のファイルを作成します。
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=()
関連するツイート
zshのバグ見つけたかもしれない
— 院死 (@mpyw) 2015, 7月 12
zsh 5.0.8 (x86_64-apple-darwin14.3.0) でこの関数セグフォします whichで確認すると内部で「a=」っていう関数が作られているのが分かります pic.twitter.com/Hqmk2HM6Z1
— 院死 (@mpyw) 2015, 7月 12
local a=() localと空配列の初期化がかぶると関数になっちゃうみたいですね pic.twitter.com/A2ame8WxpF
— 院死 (@mpyw) 2015, 7月 12
環境によってはセグフォまではいかないみたいです。
@mpyw バグっぽいけどうちの環境だとセグフォはしなかった pic.twitter.com/tV5Mqu1rBp
— れに (@rhe__) 2015, 7月 12
@mpyw local なしの a=() ls だと a っていう空配列と ls の実行になるけど、local つけると local 'a='() { ls } とパースされちゃうっぽい....?せぐふぉするのは謎
— れに (@rhe__) 2015, 7月 12