Patch 8.2.3362
Problem:    Buffer overflow when completing long tag name.
Solution:   Allocate the buffer dynamically. (Gregory Anders, closes #8769)
Files:      src/tag.c, src/testdir/test_tagjump.vim


*** ../vim-8.2.3361/src/tag.c   2021-08-11 17:01:41.614253926 +0200
--- src/tag.c   2021-08-21 16:19:03.838782152 +0200
***************
*** 3878,3900 ****
      char_u    ***file)
  {
      int               i;
!     int               c;
!     int               tagnmflag;
!     char_u      tagnm[100];
      tagptrs_T t_p;
      int               ret;
  
      if (tagnames)
!       tagnmflag = TAG_NAMES;
      else
!       tagnmflag = 0;
      if (pat[0] == '/')
        ret = find_tags(pat + 1, num_file, file,
!               TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC,
                TAG_MANY, curbuf->b_ffname);
      else
        ret = find_tags(pat, num_file, file,
!             TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC | TAG_NOIC,
                TAG_MANY, curbuf->b_ffname);
      if (ret == OK && !tagnames)
      {
--- 3878,3904 ----
      char_u    ***file)
  {
      int               i;
!     int               extra_flag;
!     char_u    *name_buf;
!     size_t    name_buf_size = 100;
      tagptrs_T t_p;
      int               ret;
  
+     name_buf = alloc(name_buf_size);
+     if (name_buf == NULL)
+       return FAIL;
+ 
      if (tagnames)
!       extra_flag = TAG_NAMES;
      else
!       extra_flag = 0;
      if (pat[0] == '/')
        ret = find_tags(pat + 1, num_file, file,
!               TAG_REGEXP | extra_flag | TAG_VERBOSE | TAG_NO_TAGFUNC,
                TAG_MANY, curbuf->b_ffname);
      else
        ret = find_tags(pat, num_file, file,
!             TAG_REGEXP | extra_flag | TAG_VERBOSE | TAG_NO_TAGFUNC | TAG_NOIC,
                TAG_MANY, curbuf->b_ffname);
      if (ret == OK && !tagnames)
      {
***************
*** 3902,3919 ****
         // "<tagname>\0<kind>\0<filename>\0"
         for (i = 0; i < *num_file; i++)
         {
             parse_match((*file)[i], &t_p);
!            c = (int)(t_p.tagname_end - t_p.tagname);
!            mch_memmove(tagnm, t_p.tagname, (size_t)c);
!            tagnm[c++] = 0;
!            tagnm[c++] = (t_p.tagkind != NULL && *t_p.tagkind)
!                                                        ? *t_p.tagkind : 'f';
!            tagnm[c++] = 0;
!            mch_memmove((*file)[i] + c, t_p.fname, t_p.fname_end - t_p.fname);
!            (*file)[i][c + (t_p.fname_end - t_p.fname)] = 0;
!            mch_memmove((*file)[i], tagnm, (size_t)c);
        }
      }
      return ret;
  }
  
--- 3906,3942 ----
         // "<tagname>\0<kind>\0<filename>\0"
         for (i = 0; i < *num_file; i++)
         {
+            size_t     len;
+ 
             parse_match((*file)[i], &t_p);
!            len = t_p.tagname_end - t_p.tagname;
!            if (len > name_buf_size - 3)
!            {
!                char_u *buf;
! 
!                name_buf_size = len + 3;
!                buf = vim_realloc(name_buf, name_buf_size);
!                if (buf == NULL)
!                {
!                    vim_free(name_buf);
!                    return FAIL;
!                }
!                name_buf = buf;
!            }
! 
!            mch_memmove(name_buf, t_p.tagname, len);
!            name_buf[len++] = 0;
!            name_buf[len++] = (t_p.tagkind != NULL && *t_p.tagkind)
!                                                         ? *t_p.tagkind : 'f';
!            name_buf[len++] = 0;
!            mch_memmove((*file)[i] + len, t_p.fname,
!                                                   t_p.fname_end - t_p.fname);
!            (*file)[i][len + (t_p.fname_end - t_p.fname)] = 0;
!            mch_memmove((*file)[i], name_buf, len);
        }
      }
+ 
+     vim_free(name_buf);
      return ret;
  }
  
*** ../vim-8.2.3361/src/testdir/test_tagjump.vim        2021-06-19 
20:45:07.353511358 +0200
--- src/testdir/test_tagjump.vim        2021-08-21 16:12:21.435785981 +0200
***************
*** 606,611 ****
--- 606,621 ----
    call assert_equal('Xsomewhere', expand('%'))
    call assert_equal(3, getcurpos()[1])
  
+   " expansion on command line works with long lines when &wildoptions contains
+   " 'tagfile'
+   set wildoptions=tagfile
+   call writefile([
+       \ 
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
      file    /^pattern$/;"   f'
+       \ ], 'Xtags')
+   call feedkeys(":tag \<Tab>", 'tx')
+   " Should not crash
+   call assert_true(v:true)
+ 
    call delete('Xtags')
    call delete('Xsomewhere')
    set tags&
*** ../vim-8.2.3361/src/version.c       2021-08-20 20:54:20.558119674 +0200
--- src/version.c       2021-08-21 16:20:47.750522640 +0200
***************
*** 757,758 ****
--- 757,760 ----
  {   /* Add new patch number below this line */
+ /**/
+     3362,
  /**/

-- 
A law to reduce crime states: "It is mandatory for a motorist with criminal
intentions to stop at the city limits and telephone the chief of police as he
is entering the town.
                [real standing law in Washington, United States of America]

 /// Bram Moolenaar -- [email protected] -- 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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202108211421.17LELqSv1109875%40masaka.moolenaar.net.

Raspunde prin e-mail lui