Patch 8.2.1539
Problem:    Using invalid script ID causes a crash.
Solution:   Check the script ID to be valid. (closes #6804)
Files:      src/globals.h, src/evalvars.c, src/profiler.c, src/scriptfile.c,
            src/vim9compile.c, src/testdir/test_vim9_script.vim


*** ../vim-8.2.1538/src/globals.h       2020-08-18 13:41:47.215350419 +0200
--- src/globals.h       2020-08-29 13:14:13.419717244 +0200
***************
*** 297,304 ****
  # endif
  EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T *), 20, NULL);
  # define SCRIPT_ITEM(id)    (((scriptitem_T **)script_items.ga_data)[(id) - 
1])
! # define SCRIPT_SV(id)            (SCRIPT_ITEM(id)->sn_vars)
! # define SCRIPT_VARS(id)    (SCRIPT_SV(id)->sv_dict.dv_hashtab)
  
  # define FUNCLINE(fp, j)      ((char_u **)(fp->uf_lines.ga_data))[j]
  
--- 297,305 ----
  # endif
  EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T *), 20, NULL);
  # define SCRIPT_ITEM(id)    (((scriptitem_T **)script_items.ga_data)[(id) - 
1])
! # define SCRIPT_ID_VALID(id)    ((id) > 0 && (id) <= script_items.ga_len)
! # define SCRIPT_SV(id)                (SCRIPT_ITEM(id)->sn_vars)
! # define SCRIPT_VARS(id)      (SCRIPT_SV(id)->sv_dict.dv_hashtab)
  
  # define FUNCLINE(fp, j)      ((char_u **)(fp->uf_lines.ga_data))[j]
  
*** ../vim-8.2.1538/src/evalvars.c      2020-08-27 21:33:06.978960755 +0200
--- src/evalvars.c      2020-08-29 13:16:02.267299403 +0200
***************
*** 524,530 ****
      static void
  list_script_vars(int *first)
  {
!     if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
        list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid),
                                                           "s:", FALSE, first);
  }
--- 524,530 ----
      static void
  list_script_vars(int *first)
  {
!     if (SCRIPT_ID_VALID(current_sctx.sc_sid))
        list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid),
                                                           "s:", FALSE, first);
  }
***************
*** 2609,2615 ****
  {
      scid_T sid = current_sctx.sc_sid;
  
!     if (sid > 0 && sid <= script_items.ga_len)
        return &SCRIPT_VARS(sid);
      return NULL;
  }
--- 2609,2615 ----
  {
      scid_T sid = current_sctx.sc_sid;
  
!     if (SCRIPT_ID_VALID(sid))
        return &SCRIPT_VARS(sid);
      return NULL;
  }
*** ../vim-8.2.1538/src/profiler.c      2020-01-26 19:26:42.794068329 +0100
--- src/profiler.c      2020-08-29 13:17:47.206908233 +0200
***************
*** 761,767 ****
  {
      scriptitem_T    *si;
  
!     if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
      {
        si = SCRIPT_ITEM(current_sctx.sc_sid);
        if (si->sn_prof_on && si->sn_pr_nest++ == 0)
--- 761,767 ----
  {
      scriptitem_T    *si;
  
!     if (SCRIPT_ID_VALID(current_sctx.sc_sid))
      {
        si = SCRIPT_ITEM(current_sctx.sc_sid);
        if (si->sn_prof_on && si->sn_pr_nest++ == 0)
***************
*** 778,784 ****
  {
      scriptitem_T    *si;
  
!     if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
      {
        si = SCRIPT_ITEM(current_sctx.sc_sid);
        if (si->sn_prof_on && --si->sn_pr_nest == 0)
--- 778,784 ----
  {
      scriptitem_T    *si;
  
!     if (SCRIPT_ID_VALID(current_sctx.sc_sid))
      {
        si = SCRIPT_ITEM(current_sctx.sc_sid);
        if (si->sn_prof_on && --si->sn_pr_nest == 0)
***************
*** 903,909 ****
      scriptitem_T    *si;
      sn_prl_T      *pp;
  
!     if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
        return;
      si = SCRIPT_ITEM(current_sctx.sc_sid);
      if (si->sn_prof_on && SOURCING_LNUM >= 1)
--- 903,909 ----
      scriptitem_T    *si;
      sn_prl_T      *pp;
  
!     if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
        return;
      si = SCRIPT_ITEM(current_sctx.sc_sid);
      if (si->sn_prof_on && SOURCING_LNUM >= 1)
***************
*** 938,944 ****
  {
      scriptitem_T    *si;
  
!     if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
        return;
      si = SCRIPT_ITEM(current_sctx.sc_sid);
      if (si->sn_prof_on && si->sn_prl_idx >= 0)
--- 938,944 ----
  {
      scriptitem_T    *si;
  
!     if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
        return;
      si = SCRIPT_ITEM(current_sctx.sc_sid);
      if (si->sn_prof_on && si->sn_prl_idx >= 0)
***************
*** 954,960 ****
      scriptitem_T    *si;
      sn_prl_T      *pp;
  
!     if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
        return;
      si = SCRIPT_ITEM(current_sctx.sc_sid);
      if (si->sn_prof_on && si->sn_prl_idx >= 0
--- 954,960 ----
      scriptitem_T    *si;
      sn_prl_T      *pp;
  
!     if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
        return;
      si = SCRIPT_ITEM(current_sctx.sc_sid);
      if (si->sn_prof_on && si->sn_prl_idx >= 0
*** ../vim-8.2.1538/src/scriptfile.c    2020-08-20 15:02:38.532535000 +0200
--- src/scriptfile.c    2020-08-29 13:18:48.846682967 +0200
***************
*** 1517,1523 ****
      if (eap->addr_count > 0)
      {
        // :script {scriptId}: edit the script
!       if (eap->line2 < 1 || eap->line2 > script_items.ga_len)
            emsg(_(e_invarg));
        else
        {
--- 1517,1523 ----
      if (eap->addr_count > 0)
      {
        // :script {scriptId}: edit the script
!       if (!SCRIPT_ID_VALID(eap->line2))
            emsg(_(e_invarg));
        else
        {
*** ../vim-8.2.1538/src/vim9compile.c   2020-08-27 23:57:50.272069276 +0200
--- src/vim9compile.c   2020-08-29 13:24:18.889518167 +0200
***************
*** 1661,1667 ****
      int                   idx;
  
      // First look the name up in the hashtable.
!     if (sid <= 0 || sid > script_items.ga_len)
        return -1;
      ht = &SCRIPT_VARS(sid);
      di = find_var_in_ht(ht, 0, name, TRUE);
--- 1661,1667 ----
      int                   idx;
  
      // First look the name up in the hashtable.
!     if (!SCRIPT_ID_VALID(sid))
        return -1;
      ht = &SCRIPT_VARS(sid);
      di = find_var_in_ht(ht, 0, name, TRUE);
***************
*** 1692,1698 ****
  {
      int                   idx;
  
!     if (current_sctx.sc_sid <= 0)
        return NULL;
      if (cctx != NULL)
        for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx)
--- 1692,1698 ----
  {
      int                   idx;
  
!     if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
        return NULL;
      if (cctx != NULL)
        for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx)
***************
*** 1712,1720 ****
      imported_T *
  find_imported_in_script(char_u *name, size_t len, int sid)
  {
!     scriptitem_T    *si = SCRIPT_ITEM(sid);
      int                   idx;
  
      for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
      {
        imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx;
--- 1712,1723 ----
      imported_T *
  find_imported_in_script(char_u *name, size_t len, int sid)
  {
!     scriptitem_T    *si;
      int                   idx;
  
+     if (!SCRIPT_ID_VALID(sid))
+       return NULL;
+     si = SCRIPT_ITEM(sid);
      for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
      {
        imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx;
***************
*** 1966,1975 ****
        char_u **end,       // end of variable
        int    error)       // when TRUE may give error
  {
!     scriptitem_T    *si = SCRIPT_ITEM(current_sctx.sc_sid);
!     int                   idx = get_script_item_idx(current_sctx.sc_sid, 
name, FALSE);
      imported_T            *import;
  
      if (idx == -1 || si->sn_version != SCRIPT_VERSION_VIM9)
      {
        // variable is not in sn_var_vals: old style script.
--- 1969,1982 ----
        char_u **end,       // end of variable
        int    error)       // when TRUE may give error
  {
!     scriptitem_T    *si;
!     int                   idx;
      imported_T            *import;
  
+     if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
+       return FAIL;
+     si = SCRIPT_ITEM(current_sctx.sc_sid);
+     idx = get_script_item_idx(current_sctx.sc_sid, name, FALSE);
      if (idx == -1 || si->sn_version != SCRIPT_VERSION_VIM9)
      {
        // variable is not in sn_var_vals: old style script.
***************
*** 4750,4764 ****
                        scriptvar_sid = current_sctx.sc_sid;
                        if (import != NULL)
                            scriptvar_sid = import->imp_sid;
!                       scriptvar_idx = get_script_item_idx(scriptvar_sid,
!                                                               rawname, TRUE);
!                       if (scriptvar_idx >= 0)
                        {
!                           scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
!                           svar_T           *sv =
                                            ((svar_T *)si->sn_var_vals.ga_data)
                                                               + scriptvar_idx;
!                           type = sv->sv_type;
                        }
                    }
                    else if (name[1] == ':' && name[2] != NUL)
--- 4757,4774 ----
                        scriptvar_sid = current_sctx.sc_sid;
                        if (import != NULL)
                            scriptvar_sid = import->imp_sid;
!                       if (SCRIPT_ID_VALID(scriptvar_sid))
                        {
!                           scriptvar_idx = get_script_item_idx(scriptvar_sid,
!                                                               rawname, TRUE);
!                           if (scriptvar_idx > 0)
!                           {
!                               scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
!                               svar_T       *sv =
                                            ((svar_T *)si->sn_var_vals.ga_data)
                                                               + scriptvar_idx;
!                               type = sv->sv_type;
!                           }
                        }
                    }
                    else if (name[1] == ':' && name[2] != NUL)
*** ../vim-8.2.1538/src/testdir/test_vim9_script.vim    2020-08-27 
22:42:59.416097708 +0200
--- src/testdir/test_vim9_script.vim    2020-08-29 13:37:07.254944378 +0200
***************
*** 4,9 ****
--- 4,10 ----
  source term_util.vim
  source view_util.vim
  source vim9.vim
+ source shared.vim
  
  def Test_syntax()
    let var = 234
***************
*** 3252,3257 ****
--- 3253,3266 ----
    delete('rtp', 'rf')
  enddef
  
+ def Test_invalid_sid()
+   assert_fails('func <SNR>1234_func', 'E123:')
+   if RunVim([], ['wq Xdidit'], '+"func <SNR>1_func"')
+     call assert_equal([], readfile('Xdidit'))
+   endif
+   delete('Xdidit')
+ enddef
+ 
  " Keep this last, it messes up highlighting.
  def Test_substitute_cmd()
    new
*** ../vim-8.2.1538/src/version.c       2020-08-29 12:57:12.587813107 +0200
--- src/version.c       2020-08-29 13:37:37.602849424 +0200
***************
*** 756,757 ****
--- 756,759 ----
  {   /* Add new patch number below this line */
+ /**/
+     1539,
  /**/

-- 
            ### Hiroshima 45, Chernobyl 86, Windows 95 ###

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202008291140.07TBelKO2512162%40masaka.moolenaar.net.

Raspunde prin e-mail lui