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 -- b...@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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202106051852.155IqCqc113220%40masaka.moolenaar.net.

Raspunde prin e-mail lui