New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

整数の最大値に近い値をスライスの添字に指定すると間違った結果が返ってくる #1049

Open
tyru opened this Issue Apr 30, 2017 · 7 comments

Comments

Projects
None yet
4 participants
@tyru
Member

tyru commented Apr 30, 2017

質問・報告の内容

以下の Vim script の式の結果が nightly build(-kaoriya), kaoriya と MSYS Vim の場合で異なります (バージョンは揃えました)。
通常スライスの右側の値 (1/0-1) がリストより大きな値の場合は最後のインデックスが指定されたのと同じ結果が得られますが、nightly build と kaoriya では間違った値が返ってきているようです。

:let list = [1,2,3][: 1/0-1]
" nightly build, kaoriya の場合
:echo list == [1,2]
" MSYS Vim の場合
:echo list == [1,2,3]
  • ちなみに nightly build, kaoriya の場合は [1,2,3][: 1/0-2] == [1][1,2,3][: 1/0-3] == [] になります
  • Vim script では 1/0 は整数の最大値が得られます

Vimのバージョン

全て 8.0.0134 です。

  • nightly build(-kaoriya, x64)
  • kaoriya(x64)
  • MSYS Vim

OSの種類/ディストリ/バージョン

Windows 10 Pro 64bit (10.0.14393 N/A ビルド 14393)

その他

関連 PR: vim-jp/vital.vim#498 (comment)

@tyru tyru referenced this issue Apr 30, 2017

Closed

Add Stream module #498

75 of 75 tasks complete
@tyru

This comment has been minimized.

Show comment
Hide comment
@tyru

tyru Apr 30, 2017

Member

左側のスライスの場合も結果が異なるようです。

:let list = [1,2,3][1/0 :]
" nightly build, kaoriya の場合
:echo list == [1,2,3]
" MSYS Vim の場合
:echo list == []

:let list = [1,2,3][1/0-1 :]
" nightly build, kaoriya の場合
:echo list == [3]
" MSYS Vim の場合
:echo list == []

:let list = [1,2,3][1/0-2 :]
" nightly build, kaoriya の場合
:echo list == [2,3]
" MSYS Vim の場合
:echo list == []
Member

tyru commented Apr 30, 2017

左側のスライスの場合も結果が異なるようです。

:let list = [1,2,3][1/0 :]
" nightly build, kaoriya の場合
:echo list == [1,2,3]
" MSYS Vim の場合
:echo list == []

:let list = [1,2,3][1/0-1 :]
" nightly build, kaoriya の場合
:echo list == [3]
" MSYS Vim の場合
:echo list == []

:let list = [1,2,3][1/0-2 :]
" nightly build, kaoriya の場合
:echo list == [2,3]
" MSYS Vim の場合
:echo list == []

tyru added a commit to vim-jp/vital.vim that referenced this issue Apr 30, 2017

@k-takata

This comment has been minimized.

Show comment
Hide comment
@k-takata

k-takata Apr 30, 2017

Member

どこかで long 型を使っているのが原因だと推測します。
Windowsでは64bit環境でもlongは32bitです。
Cygwin/MSYSではLinuxに合わせて、64bit環境ならlongも64bitです。

Member

k-takata commented Apr 30, 2017

どこかで long 型を使っているのが原因だと推測します。
Windowsでは64bit環境でもlongは32bitです。
Cygwin/MSYSではLinuxに合わせて、64bit環境ならlongも64bitです。

@k-takata

This comment has been minimized.

Show comment
Hide comment
@k-takata

k-takata May 1, 2017

Member

1/0-1 の結果を 32bit 符号付き整数で表すと -2 になって、[1,2,3][: 1/0-1][1,2] になっていると思われます。

Member

k-takata commented May 1, 2017

1/0-1 の結果を 32bit 符号付き整数で表すと -2 になって、[1,2,3][: 1/0-1][1,2] になっていると思われます。

@mattn

This comment has been minimized.

Show comment
Hide comment
Member

mattn commented May 1, 2017

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 1, 2017

Member

eval_index の n1, n2, len じゃないかな。

そうですね👍
実際には文字列なので1ブロック上のL4591~L4624かな。

これ、「Vim scriptの整数の内部の取扱をvarnumber_T型にする」というお題とすると修正範囲広い気がします。

eval.c : 4610

	s = vim_strnsave(s + n1, (int)(n2 - n1 + 1));

これを見る限りvim_strnsave(), vim_strsave(), alloc()も対策が必要。

とりあえず、途中までやったpatch↓
https://gist.github.com/h-east/a22b305ddfdd1b1b6862912da5142959

本Issueの手順で起こる問題は解消されています。
(vim_strnsave(), vim_strsave(), alloc()の修正はやっていない)

Member

h-east commented May 1, 2017

eval_index の n1, n2, len じゃないかな。

そうですね👍
実際には文字列なので1ブロック上のL4591~L4624かな。

これ、「Vim scriptの整数の内部の取扱をvarnumber_T型にする」というお題とすると修正範囲広い気がします。

eval.c : 4610

	s = vim_strnsave(s + n1, (int)(n2 - n1 + 1));

これを見る限りvim_strnsave(), vim_strsave(), alloc()も対策が必要。

とりあえず、途中までやったpatch↓
https://gist.github.com/h-east/a22b305ddfdd1b1b6862912da5142959

本Issueの手順で起こる問題は解消されています。
(vim_strnsave(), vim_strsave(), alloc()の修正はやっていない)

@k-takata

This comment has been minimized.

Show comment
Hide comment
@k-takata

k-takata May 1, 2017

Member

よく考えると32bit Linux等でも発生しそう。32bit環境では配列のインデックスは何bitにすべきなんですかね?

Member

k-takata commented May 1, 2017

よく考えると32bit Linux等でも発生しそう。32bit環境では配列のインデックスは何bitにすべきなんですかね?

tyru added a commit to vim-jp/vital.vim that referenced this issue May 3, 2017

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 11, 2017

Member

List, String, Sub-List, Sub-Stringのindexに 9223372036854775807 (2^63-1)まで指定出来たとしても、そういうオブジェクトが存在するためにはそれだけのメモリ確保が出来ないといけない訳で、、、もちろんそんなの無理なわけで、、

32bitでさえ以下のような状況なので32bitのままでいいんじゃないかと思います。
もしくは、もっと小さい値に既定してしまうとか。(←無理か?)

let x=repeat("X", 2147483646)                 " 2^31-1 -1 (終端NULの分)

応答あるまで30秒。

:echo len(x)

90秒後にエラー。
E342: Out of memory! (allocating 2147483647 bytes)

(環境: fedora 25 64bit on VitrualBox)

とりあえず、Bram氏に問題提起しましょうか?

Member

h-east commented May 11, 2017

List, String, Sub-List, Sub-Stringのindexに 9223372036854775807 (2^63-1)まで指定出来たとしても、そういうオブジェクトが存在するためにはそれだけのメモリ確保が出来ないといけない訳で、、、もちろんそんなの無理なわけで、、

32bitでさえ以下のような状況なので32bitのままでいいんじゃないかと思います。
もしくは、もっと小さい値に既定してしまうとか。(←無理か?)

let x=repeat("X", 2147483646)                 " 2^31-1 -1 (終端NULの分)

応答あるまで30秒。

:echo len(x)

90秒後にエラー。
E342: Out of memory! (allocating 2147483647 bytes)

(環境: fedora 25 64bit on VitrualBox)

とりあえず、Bram氏に問題提起しましょうか?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment