diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-06-05 20:51:38 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-06-05 20:51:38 +0200 |
commit | 1328bde9d406aa1292e92673fa8a026889424e79 (patch) | |
tree | a0415264993e4c6bc6ecf5d982aa20032b5d5af4 /src | |
parent | c6d71532dda0b3a244907bb5d1826f9340f7571d (diff) |
patch 8.2.2944: Vim9: no error when using job or channel as a stringv8.2.2944
Problem: Vim9: no error when using job or channel as a string.
Solution: Be more strict about conversion to string. (closes #8312)
Diffstat (limited to 'src')
-rw-r--r-- | src/channel.c | 18 | ||||
-rw-r--r-- | src/eval.c | 3 | ||||
-rw-r--r-- | src/job.c | 30 | ||||
-rw-r--r-- | src/proto/channel.pro | 1 | ||||
-rw-r--r-- | src/proto/job.pro | 1 | ||||
-rw-r--r-- | src/testdir/test_vim9_builtin.vim | 12 | ||||
-rw-r--r-- | src/typval.c | 40 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9execute.c | 3 |
9 files changed, 76 insertions, 34 deletions
diff --git a/src/channel.c b/src/channel.c index fa329bdba3..2a93e2578c 100644 --- a/src/channel.c +++ b/src/channel.c @@ -5015,4 +5015,22 @@ f_ch_status(typval_T *argvars, typval_T *rettv) 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 diff --git a/src/eval.c b/src/eval.c index 77578f3650..1fb1f5e70b 100644 --- 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); @@ -1927,4 +1927,34 @@ f_job_stop(typval_T *argvars, typval_T *rettv) 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 diff --git a/src/proto/channel.pro b/src/proto/channel.pro index bbe5288a38..32e68d8942 100644 --- a/src/proto/channel.pro +++ b/src/proto/channel.pro @@ -58,4 +58,5 @@ void f_ch_evalraw(typval_T *argvars, typval_T *rettv); 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 : */ diff --git a/src/proto/job.pro b/src/proto/job.pro index bf97577e12..3927e7f48e 100644 --- a/src/proto/job.pro +++ b/src/proto/job.pro @@ -34,4 +34,5 @@ void f_job_setoptions(typval_T *argvars, typval_T *rettv); 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 : */ diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 9cae4a34e1..b98c840ce0 100644 --- 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") diff --git a/src/typval.c b/src/typval.c index 3d1bd7f53f..f08d1aa421 100644 --- 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 *varp, char_u *buf, int strict) 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: diff --git a/src/version.c b/src/version.c index 87bc2a09ed..b729c99f5e 100644 --- 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, diff --git a/src/vim9execute.c b/src/vim9execute.c index 455a205070..a13b0ab986 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -4831,10 +4831,11 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc) { 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 |