Patch 9.0.0742
Problem:    Reading past end of the line when compiling a function with
            errors.
Solution:   Do not return an invalid pointer.  Fix skipping redirection.
Files:      src/vim9compile.c, src/vim9cmds.c, src/testdir/test_vim9_func.vim,
            src/testdir/test_vim9_script.vim


*** ../vim-9.0.0741/src/vim9compile.c   2022-10-11 20:04:05.880795466 +0100
--- src/vim9compile.c   2022-10-13 16:11:09.580587352 +0100
***************
*** 1284,1289 ****
--- 1284,1302 ----
  }
  
  /*
+  * Return TRUE if "name" is a valid register to use.
+  * Return FALSE and give an error message if not.
+  */
+     static int
+ valid_dest_reg(int name)
+ {
+     if ((name == '@' || valid_yank_reg(name, FALSE)) && name != '.')
+       return TRUE;
+     emsg_invreg(name);
+     return FAIL;
+ }
+ 
+ /*
   * For one assignment figure out the type of destination.  Return it in 
"dest".
   * When not recognized "dest" is not set.
   * For an option "option_scope" is set.
***************
*** 1364,1375 ****
      }
      else if (*name == '@')
      {
!       if (name[1] != '@'
!                       && (!valid_yank_reg(name[1], FALSE) || name[1] == '.'))
!       {
!           emsg_invreg(name[1]);
            return FAIL;
-       }
        *dest = dest_reg;
        *type = name[1] == '#' ? &t_number_or_string : &t_string;
      }
--- 1377,1384 ----
      }
      else if (*name == '@')
      {
!       if (!valid_dest_reg(name[1]))
            return FAIL;
        *dest = dest_reg;
        *type = name[1] == '#' ? &t_number_or_string : &t_string;
      }
***************
*** 1445,1451 ****
--- 1454,1464 ----
      // "var_end" is the end of the variable/option/etc. name.
      lhs->lhs_dest_end = skip_var_one(var_start, FALSE);
      if (*var_start == '@')
+     {
+       if (!valid_dest_reg(var_start[1]))
+           return FAIL;
        var_end = var_start + 2;
+     }
      else
      {
        // skip over the leading "&", "&l:", "&g:" and "$"
*** ../vim-9.0.0741/src/vim9cmds.c      2022-10-11 21:41:21.446173722 +0100
--- src/vim9cmds.c      2022-10-13 15:53:05.036099874 +0100
***************
*** 2412,2445 ****
      {
        if (STRNCMP(arg, "END", 3) == 0)
        {
!           if (lhs->lhs_append)
            {
!               // First load the current variable value.
!               if (compile_load_lhs_with_index(lhs, lhs->lhs_whole,
                                                                 cctx) == FAIL)
!                   return NULL;
!           }
! 
!           // Gets the redirected text and put it on the stack, then store it
!           // in the variable.
!           generate_instr_type(cctx, ISN_REDIREND, &t_string);
! 
!           if (lhs->lhs_append)
!               generate_CONCAT(cctx, 2);
  
!           if (lhs->lhs_has_index)
!           {
!               // Use the info in "lhs" to store the value at the index in the
!               // list or dict.
!               if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE,
                                                      &t_string, cctx) == FAIL)
                    return NULL;
-           }
-           else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL)
-               return NULL;
  
!           VIM_CLEAR(lhs->lhs_name);
!           VIM_CLEAR(lhs->lhs_whole);
            return arg + 3;
        }
        emsg(_(e_cannot_nest_redir));
--- 2412,2448 ----
      {
        if (STRNCMP(arg, "END", 3) == 0)
        {
!           if (cctx->ctx_skip != SKIP_YES)
            {
!               if (lhs->lhs_append)
!               {
!                   // First load the current variable value.
!                   if (compile_load_lhs_with_index(lhs, lhs->lhs_whole,
                                                                 cctx) == FAIL)
!                       return NULL;
!               }
  
!               // Gets the redirected text and put it on the stack, then store
!               // it in the variable.
!               generate_instr_type(cctx, ISN_REDIREND, &t_string);
! 
!               if (lhs->lhs_append)
!                   generate_CONCAT(cctx, 2);
! 
!               if (lhs->lhs_has_index)
!               {
!                   // Use the info in "lhs" to store the value at the index in
!                   // the list or dict.
!                   if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE,
                                                      &t_string, cctx) == FAIL)
+                       return NULL;
+               }
+               else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL)
                    return NULL;
  
!               VIM_CLEAR(lhs->lhs_name);
!               VIM_CLEAR(lhs->lhs_whole);
!           }
            return arg + 3;
        }
        emsg(_(e_cannot_nest_redir));
***************
*** 2465,2477 ****
        if (need_type(&t_string, lhs->lhs_member_type,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
            return NULL;
!       generate_instr(cctx, ISN_REDIRSTART);
!       lhs->lhs_append = append;
!       if (lhs->lhs_has_index)
        {
!           lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total);
!           if (lhs->lhs_whole == NULL)
!               return NULL;
        }
  
        return arg + lhs->lhs_varlen_total;
--- 2468,2487 ----
        if (need_type(&t_string, lhs->lhs_member_type,
                                            -1, 0, cctx, FALSE, FALSE) == FAIL)
            return NULL;
!       if (cctx->ctx_skip == SKIP_YES)
!       {
!           VIM_CLEAR(lhs->lhs_name);
!       }
!       else
        {
!           generate_instr(cctx, ISN_REDIRSTART);
!           lhs->lhs_append = append;
!           if (lhs->lhs_has_index)
!           {
!               lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total);
!               if (lhs->lhs_whole == NULL)
!                   return NULL;
!           }
        }
  
        return arg + lhs->lhs_varlen_total;
*** ../vim-9.0.0741/src/testdir/test_vim9_func.vim      2022-09-30 
19:19:00.769677730 +0100
--- src/testdir/test_vim9_func.vim      2022-10-13 15:39:22.488958480 +0100
***************
*** 4339,4344 ****
--- 4339,4371 ----
    assert_equal('', glob('XdeferFile'))
  enddef
  
+ def Test_invalid_redir()
+   var lines =<< trim END
+       def Tone()
+         if 1
+           redi =>@                        \\\
\\\        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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221013151343.4CDEB1C0760%40moolenaar.net.

Raspunde prin e-mail lui