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

matchstrpos() の返り値の要素数が不安定 #1075

Closed
machakann opened this Issue Aug 26, 2017 · 6 comments

Comments

Projects
None yet
3 participants
@machakann

machakann commented Aug 26, 2017

質問・報告の内容

matchstrpos() の第一引数 {expr} に文字列を与えた場合、返り値の要素数は通常三つなのですが、第三引数の {start} が文字列長より長くなった場合、要素数四つのリストが返ります。

echo matchstrpos('abc','a',0)  " ['a', 0, 1]
echo matchstrpos('abc','a',4)  " ['', -1, -1, -1]

おそらく意図しない動作だと思うのですが、返り値の要素数は固定のほうが嬉しいです。

Vimのバージョン

8.0.983

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

  • Windows 10 Pro 64bit

@machakann machakann changed the title from matchstrpos() no to matchstrpos() の返り値の要素数が不安定 Aug 26, 2017

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east Aug 26, 2017

Member

これで直ると思います。
問題なければtest追加してvim_devに送付します。

diff --git a/src/evalfunc.c b/src/evalfunc.c
index c85c334..45a9e91 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -7472,12 +7472,11 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
 	vim_regfree(regmatch.regprog);
     }
 
+theend:
     if (type == 4 && l == NULL)
 	/* matchstrpos() without a list: drop the second item. */
 	listitem_remove(rettv->vval.v_list,
 				       rettv->vval.v_list->lv_first->li_next);
-
-theend:
     vim_free(tofree);
     p_cpo = save_cpo;
 }
Member

h-east commented Aug 26, 2017

これで直ると思います。
問題なければtest追加してvim_devに送付します。

diff --git a/src/evalfunc.c b/src/evalfunc.c
index c85c334..45a9e91 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -7472,12 +7472,11 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
 	vim_regfree(regmatch.regprog);
     }
 
+theend:
     if (type == 4 && l == NULL)
 	/* matchstrpos() without a list: drop the second item. */
 	listitem_remove(rettv->vval.v_list,
 				       rettv->vval.v_list->lv_first->li_next);
-
-theend:
     vim_free(tofree);
     p_cpo = save_cpo;
 }

@h-east h-east self-assigned this Aug 26, 2017

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Aug 26, 2017

Member

https://github.com/vim/vim/blob/master/src/evalfunc.c#L7298
rettv->vval.v_list = NULLtheend に飛ぶケースがあるので rettv->vval.v_list != NULL のチェックが必要かと。

Member

ichizok commented Aug 26, 2017

https://github.com/vim/vim/blob/master/src/evalfunc.c#L7298
rettv->vval.v_list = NULLtheend に飛ぶケースがあるので rettv->vval.v_list != NULL のチェックが必要かと。

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east Aug 27, 2017

Member

@ichizok That's right. Thanks!

testも追加しました。

diff --git a/src/evalfunc.c b/src/evalfunc.c
index c85c334..958b1bc 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -7472,12 +7472,11 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
 	vim_regfree(regmatch.regprog);
     }
 
-    if (type == 4 && l == NULL)
+theend:
+    if (type == 4 && l == NULL && rettv->vval.v_list != NULL)
 	/* matchstrpos() without a list: drop the second item. */
 	listitem_remove(rettv->vval.v_list,
 				       rettv->vval.v_list->lv_first->li_next);
-
-theend:
     vim_free(tofree);
     p_cpo = save_cpo;
 }
diff --git a/src/testdir/test_match.vim b/src/testdir/test_match.vim
index 9398ef2..a3c0c91 100644
--- a/src/testdir/test_match.vim
+++ b/src/testdir/test_match.vim
@@ -152,13 +152,10 @@ endfunc
 
 func Test_matchstrpos()
   call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing'))
-
   call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2))
-
   call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5))
-
+  call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 8))
   call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing'))
-
   call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img'))
 endfunc
 
Member

h-east commented Aug 27, 2017

@ichizok That's right. Thanks!

testも追加しました。

diff --git a/src/evalfunc.c b/src/evalfunc.c
index c85c334..958b1bc 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -7472,12 +7472,11 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
 	vim_regfree(regmatch.regprog);
     }
 
-    if (type == 4 && l == NULL)
+theend:
+    if (type == 4 && l == NULL && rettv->vval.v_list != NULL)
 	/* matchstrpos() without a list: drop the second item. */
 	listitem_remove(rettv->vval.v_list,
 				       rettv->vval.v_list->lv_first->li_next);
-
-theend:
     vim_free(tofree);
     p_cpo = save_cpo;
 }
diff --git a/src/testdir/test_match.vim b/src/testdir/test_match.vim
index 9398ef2..a3c0c91 100644
--- a/src/testdir/test_match.vim
+++ b/src/testdir/test_match.vim
@@ -152,13 +152,10 @@ endfunc
 
 func Test_matchstrpos()
   call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing'))
-
   call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2))
-
   call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5))
-
+  call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 8))
   call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing'))
-
   call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img'))
 endfunc
 
@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east
Member

h-east commented Aug 27, 2017

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east Aug 27, 2017

Member

8.0.1004
vim/vim@8d9f0ef

@machakann issue登録ありがとうございました。

Member

h-east commented Aug 27, 2017

8.0.1004
vim/vim@8d9f0ef

@machakann issue登録ありがとうございました。

@h-east h-east closed this Aug 27, 2017

@h-east h-east added the xlose/fixed label Aug 27, 2017

@machakann

This comment has been minimized.

Show comment
Hide comment
@machakann

machakann Aug 27, 2017

ありがとうございました。

machakann commented Aug 27, 2017

ありがとうございました。

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