Patch 9.0.1532
Problem:    Crash when expanding "~" in substitute causes very long text.
Solution:   Limit the text length to MAXCOL.
Files:      src/regexp.c, src/testdir/test_substitute.vim


*** ../vim-9.0.1531/src/regexp.c        2023-03-12 21:20:51.441254187 +0000
--- src/regexp.c        2023-05-09 20:56:52.117482566 +0100
***************
*** 1767,1776 ****
  regtilde(char_u *source, int magic)
  {
      char_u    *newsub = source;
-     char_u    *tmpsub;
      char_u    *p;
-     int               len;
-     int               prevlen;
  
      for (p = newsub; *p; ++p)
      {
--- 1767,1773 ----
***************
*** 1779,1802 ****
            if (reg_prev_sub != NULL)
            {
                // length = len(newsub) - 1 + len(prev_sub) + 1
!               prevlen = (int)STRLEN(reg_prev_sub);
!               tmpsub = alloc(STRLEN(newsub) + prevlen);
                if (tmpsub != NULL)
                {
                    // copy prefix
!                   len = (int)(p - newsub);    // not including ~
!                   mch_memmove(tmpsub, newsub, (size_t)len);
                    // interpret tilde
!                   mch_memmove(tmpsub + len, reg_prev_sub, (size_t)prevlen);
                    // copy postfix
                    if (!magic)
                        ++p;                    // back off backslash
!                   STRCPY(tmpsub + len + prevlen, p + 1);
  
!                   if (newsub != source)       // already allocated newsub
                        vim_free(newsub);
                    newsub = tmpsub;
!                   p = newsub + len + prevlen;
                }
            }
            else if (magic)
--- 1776,1810 ----
            if (reg_prev_sub != NULL)
            {
                // length = len(newsub) - 1 + len(prev_sub) + 1
!               // Avoid making the text longer than MAXCOL, it will cause
!               // trouble at some point.
!               size_t  prevsublen = STRLEN(reg_prev_sub);
!               size_t  newsublen = STRLEN(newsub);
!               if (prevsublen > MAXCOL || newsublen > MAXCOL
!                                           || newsublen + prevsublen > MAXCOL)
!               {
!                   emsg(_(e_resulting_text_too_long));
!                   break;
!               }
! 
!               char_u *tmpsub = alloc(newsublen + prevsublen);
                if (tmpsub != NULL)
                {
                    // copy prefix
!                   size_t prefixlen = p - newsub;      // not including ~
!                   mch_memmove(tmpsub, newsub, prefixlen);
                    // interpret tilde
!                   mch_memmove(tmpsub + prefixlen, reg_prev_sub,
!                                                              prevsublen);
                    // copy postfix
                    if (!magic)
                        ++p;                    // back off backslash
!                   STRCPY(tmpsub + prefixlen + prevsublen, p + 1);
  
!                   if (newsub != source)       // allocated newsub before
                        vim_free(newsub);
                    newsub = tmpsub;
!                   p = newsub + prefixlen + prevsublen;
                }
            }
            else if (magic)
*** ../vim-9.0.1531/src/testdir/test_substitute.vim     2023-01-28 
19:18:56.733720607 +0000
--- src/testdir/test_substitute.vim     2023-05-09 21:14:38.977854684 +0100
***************
*** 1414,1419 ****
--- 1414,1433 ----
    bw!
  endfunc
  
+ " Check handling expanding "~" resulting in extremely long text.
+ func Test_substitute_tilde_too_long()
+   enew!
+ 
+   s/.*/ixxx
+   s//~~~~~~~~~AAAAAAA@(
+ 
+   " Either fails with "out of memory" or "text too long".
+   " This can take a long time.
+   call assert_fails('sil! norm &&&&&&&&&', ['E1240:\|E342:'])
+ 
+   bwipe!
+ endfunc
+ 
  " This should be done last to reveal a memory leak when vim_regsub_both() is
  " called to evaluate an expression but it is not used in a second call.
  func Test_z_substitute_expr_leak()
*** ../vim-9.0.1531/src/version.c       2023-05-09 17:09:25.657491200 +0100
--- src/version.c       2023-05-09 19:51:14.179975122 +0100
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1532,
  /**/

-- 
Far back in the mists of ancient time, in the great and glorious days of the
former Galactic Empire, life was wild, rich and largely tax free.
Mighty starships plied their way between exotic suns, seeking adventure and
reward among the furthest reaches of Galactic space.  In those days, spirits
were brave, the stakes were high, men were real men, women were real women
and small furry creatures from Alpha Centauri were real small furry creatures
from Alpha Centauri.  And all dared to brave unknown terrors, to do mighty
deeds, to boldly split infinitives that no man had split before -- and thus
was the Empire forged.
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// 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/20230509201600.965151C1B21%40moolenaar.net.

Reply via email to