To: vim_dev@googlegroups.com Subject: Patch 8.2.2944 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2944 Problem: Vim9: no error when using job or channel as a string. Solution: Be more strict about conversion to string. (closes #8312) Files: src/typval.c, src/job.c, src/proto/job.pro, src/channel.c, src/proto/channel.pro, src/eval.c, src/vim9execute.c, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.2943/src/typval.c 2021-05-09 23:19:17.093003109 +0200 --- src/typval.c 2021-06-05 20:42:37.974740560 +0200 *************** *** 414,420 **** char_u * tv_get_string_buf(typval_T *varp, char_u *buf) { ! char_u *res = tv_get_string_buf_chk(varp, buf); return res != NULL ? res : (char_u *)""; } --- 414,420 ---- char_u * tv_get_string_buf(typval_T *varp, char_u *buf) { ! char_u *res = tv_get_string_buf_chk(varp, buf); return res != NULL ? res : (char_u *)""; } *************** *** 478,521 **** break; case VAR_JOB: #ifdef FEAT_JOB_CHANNEL { ! 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 break; case VAR_CHANNEL: #ifdef FEAT_JOB_CHANNEL { ! 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 break; case VAR_UNKNOWN: --- 478,499 ---- break; case VAR_JOB: #ifdef FEAT_JOB_CHANNEL + if (in_vim9script()) { ! 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()) { ! semsg(_(e_using_invalid_value_as_string_str), "channel"); ! break; } + return channel_to_string_buf(varp, buf); #endif break; case VAR_UNKNOWN: *** ../vim-8.2.2943/src/job.c 2020-12-09 13:16:09.970838581 +0100 --- src/job.c 2021-06-05 20:40:14.811192286 +0200 *************** *** 1927,1930 **** --- 1927,1960 ---- 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 *** ../vim-8.2.2943/src/proto/job.pro 2020-09-05 15:48:32.469546692 +0200 --- src/proto/job.pro 2021-06-05 20:40:29.843144301 +0200 *************** *** 34,37 **** --- 34,38 ---- 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 : */ *** ../vim-8.2.2943/src/channel.c 2021-03-27 21:23:27.064153032 +0100 --- src/channel.c 2021-06-05 20:41:08.351021945 +0200 *************** *** 5015,5018 **** --- 5015,5036 ---- 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 *** ../vim-8.2.2943/src/proto/channel.pro 2020-09-05 15:48:32.469546692 +0200 --- src/proto/channel.pro 2021-06-05 20:41:57.286867748 +0200 *************** *** 58,61 **** --- 58,62 ---- 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 : */ *** ../vim-8.2.2943/src/eval.c 2021-06-02 17:07:02.280398156 +0200 --- src/eval.c 2021-06-05 20:41:51.342886407 +0200 *************** *** 5060,5066 **** case VAR_JOB: case VAR_CHANNEL: *tofree = NULL; ! r = tv_get_string_buf(tv, numbuf); if (composite_val) { *tofree = string_quote(r, FALSE); --- 5060,5067 ---- case VAR_JOB: case VAR_CHANNEL: *tofree = NULL; ! 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); *** ../vim-8.2.2943/src/vim9execute.c 2021-06-05 18:49:35.281702568 +0200 --- src/vim9execute.c 2021-06-05 20:50:11.713367325 +0200 *************** *** 4831,4840 **** { typval_T tv; char_u *name; tv.v_type = VAR_JOB; tv.vval.v_job = iptr->isn_arg.job; ! name = tv_get_string(&tv); smsg("%s%4d PUSHJOB \"%s\"", pfx, current, name); } #endif --- 4831,4841 ---- { typval_T tv; char_u *name; + char_u buf[NUMBUFLEN]; tv.v_type = VAR_JOB; tv.vval.v_job = iptr->isn_arg.job; ! name = job_to_string_buf(&tv, buf); smsg("%s%4d PUSHJOB \"%s\"", pfx, current, name); } #endif *** ../vim-8.2.2943/src/testdir/test_vim9_builtin.vim 2021-06-05 18:15:06.614037266 +0200 --- src/testdir/test_vim9_builtin.vim 2021-06-05 20:45:22.922232926 +0200 *************** *** 1104,1110 **** assert_equal([], getbufline(b, 2, 1)) if has('job') ! setbufline(b, 2, [function('eval'), {key: 123}, test_null_job()]) assert_equal(["function('eval')", "{'key': 123}", "no process"], --- 1104,1110 ---- assert_equal([], getbufline(b, 2, 1)) if has('job') ! setbufline(b, 2, [function('eval'), {key: 123}, string(test_null_job())]) assert_equal(["function('eval')", "{'key': 123}", "no process"], *************** *** 1250,1255 **** --- 1250,1265 ---- 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") *** ../vim-8.2.2943/src/version.c 2021-06-05 18:49:35.281702568 +0200 --- src/version.c 2021-06-05 20:26:34.089725440 +0200 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2944, /**/ -- JOHN CLEESE PLAYED: SECOND SOLDIER WITH A KEEN INTEREST IN BIRDS, LARGE MAN WITH DEAD BODY, BLACK KNIGHT, MR NEWT (A VILLAGE BLACKSMITH INTERESTED IN BURNING WITCHES), A QUITE EXTRAORDINARILY RUDE FRENCHMAN, TIM THE WIZARD, SIR LAUNCELOT "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///