Mercurial > vim
changeset 24812:8fdf839af1f4 v8.2.2944
patch 8.2.2944: Vim9: no error when using job or channel as a string
Commit: https://github.com/vim/vim/commit/1328bde9d406aa1292e92673fa8a026889424e79
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jun 5 20:51:38 2021 +0200
patch 8.2.2944: Vim9: no error when using job or channel as a string
Problem: Vim9: no error when using job or channel as a string.
Solution: Be more strict about conversion to string. (closes https://github.com/vim/vim/issues/8312)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 05 Jun 2021 21:00:03 +0200 |
parents | e89d42919a21 |
children | fd32e504070c |
files | src/channel.c src/eval.c src/job.c src/proto/channel.pro src/proto/job.pro src/testdir/test_vim9_builtin.vim src/typval.c src/version.c src/vim9execute.c |
diffstat | 9 files changed, 76 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/src/channel.c +++ b/src/channel.c @@ -5015,4 +5015,22 @@ f_ch_status(typval_T *argvars, typval_T rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel, part)); } +/* + * Get a string with information about the channel in "varp" in "buf". + * "buf" must be at least NUMBUFLEN long. + */ + char_u * +channel_to_string_buf(typval_T *varp, char_u *buf) +{ + channel_T *channel = varp->vval.v_channel; + char *status = channel_status(channel, -1); + + if (channel == NULL) + vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status); + else + vim_snprintf((char *)buf, NUMBUFLEN, + "channel %d %s", channel->ch_id, status); + return buf; +} + #endif // FEAT_JOB_CHANNEL
--- a/src/eval.c +++ b/src/eval.c @@ -5060,7 +5060,8 @@ echo_string_core( case VAR_JOB: case VAR_CHANNEL: *tofree = NULL; - r = tv_get_string_buf(tv, numbuf); + r = tv->v_type == VAR_JOB ? job_to_string_buf(tv, numbuf) + : channel_to_string_buf(tv, numbuf); if (composite_val) { *tofree = string_quote(r, FALSE);
--- a/src/job.c +++ b/src/job.c @@ -1927,4 +1927,34 @@ f_job_stop(typval_T *argvars, typval_T * rettv->vval.v_number = job_stop(job, argvars, NULL); } +/* + * Get a string with information about the job in "varp" in "buf". + * "buf" must be at least NUMBUFLEN long. + */ + char_u * +job_to_string_buf(typval_T *varp, char_u *buf) +{ + job_T *job = varp->vval.v_job; + char *status; + + if (job == NULL) + return (char_u *)"no process"; + status = job->jv_status == JOB_FAILED ? "fail" + : job->jv_status >= JOB_ENDED ? "dead" + : "run"; +# ifdef UNIX + vim_snprintf((char *)buf, NUMBUFLEN, + "process %ld %s", (long)job->jv_pid, status); +# elif defined(MSWIN) + vim_snprintf((char *)buf, NUMBUFLEN, + "process %ld %s", + (long)job->jv_proc_info.dwProcessId, + status); +# else + // fall-back + vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status); +# endif + return buf; +} + #endif // FEAT_JOB_CHANNEL
--- a/src/proto/channel.pro +++ b/src/proto/channel.pro @@ -58,4 +58,5 @@ void f_ch_evalraw(typval_T *argvars, typ void f_ch_sendraw(typval_T *argvars, typval_T *rettv); void f_ch_setoptions(typval_T *argvars, typval_T *rettv); void f_ch_status(typval_T *argvars, typval_T *rettv); +char_u *channel_to_string_buf(typval_T *varp, char_u *buf); /* vim: set ft=c : */
--- a/src/proto/job.pro +++ b/src/proto/job.pro @@ -34,4 +34,5 @@ void f_job_setoptions(typval_T *argvars, void f_job_start(typval_T *argvars, typval_T *rettv); void f_job_status(typval_T *argvars, typval_T *rettv); void f_job_stop(typval_T *argvars, typval_T *rettv); +char_u *job_to_string_buf(typval_T *varp, char_u *buf); /* vim: set ft=c : */
--- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -1104,7 +1104,7 @@ def Test_set_get_bufline() assert_equal([], getbufline(b, 2, 1)) if has('job') - setbufline(b, 2, [function('eval'), {key: 123}, test_null_job()]) + setbufline(b, 2, [function('eval'), {key: 123}, string(test_null_job())]) assert_equal(["function('eval')", "{'key': 123}", "no process"], @@ -1250,6 +1250,16 @@ def Test_submatch() actual->assert_equal(expected) enddef +def Test_substitute() + var res = substitute('A1234', '\d', 'X', '') + assert_equal('AX234', res) + + if has('job') + assert_fails('"text"->substitute(".*", () => job_start(":"), "")', 'E908: using an invalid value as a String: job') + assert_fails('"text"->substitute(".*", () => job_start(":")->job_getchannel(), "")', 'E908: using an invalid value as a String: channel') + endif +enddef + def Test_synID() new setline(1, "text")
--- a/src/typval.c +++ b/src/typval.c @@ -414,7 +414,7 @@ tv_get_string_strict(typval_T *varp) char_u * tv_get_string_buf(typval_T *varp, char_u *buf) { - char_u *res = tv_get_string_buf_chk(varp, buf); + char_u *res = tv_get_string_buf_chk(varp, buf); return res != NULL ? res : (char_u *)""; } @@ -478,44 +478,22 @@ tv_get_string_buf_chk_strict(typval_T *v break; case VAR_JOB: #ifdef FEAT_JOB_CHANNEL + if (in_vim9script()) { - job_T *job = varp->vval.v_job; - char *status; - - if (job == NULL) - return (char_u *)"no process"; - status = job->jv_status == JOB_FAILED ? "fail" - : job->jv_status >= JOB_ENDED ? "dead" - : "run"; -# ifdef UNIX - vim_snprintf((char *)buf, NUMBUFLEN, - "process %ld %s", (long)job->jv_pid, status); -# elif defined(MSWIN) - vim_snprintf((char *)buf, NUMBUFLEN, - "process %ld %s", - (long)job->jv_proc_info.dwProcessId, - status); -# else - // fall-back - vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status); -# endif - return buf; + semsg(_(e_using_invalid_value_as_string_str), "job"); + break; } + return job_to_string_buf(varp, buf); #endif break; case VAR_CHANNEL: #ifdef FEAT_JOB_CHANNEL + if (in_vim9script()) { - channel_T *channel = varp->vval.v_channel; - char *status = channel_status(channel, -1); - - if (channel == NULL) - vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status); - else - vim_snprintf((char *)buf, NUMBUFLEN, - "channel %d %s", channel->ch_id, status); - return buf; + semsg(_(e_using_invalid_value_as_string_str), "channel"); + break; } + return channel_to_string_buf(varp, buf); #endif break; case VAR_UNKNOWN:
--- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2944, +/**/ 2943, /**/ 2942,
--- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -4831,10 +4831,11 @@ list_instructions(char *pfx, isn_T *inst { typval_T tv; char_u *name; + char_u buf[NUMBUFLEN]; tv.v_type = VAR_JOB; tv.vval.v_job = iptr->isn_arg.job; - name = tv_get_string(&tv); + name = job_to_string_buf(&tv, buf); smsg("%s%4d PUSHJOB \"%s\"", pfx, current, name); } #endif