Patch 8.2.3601
Problem:    Check for overflow in put count does not work well.
Solution:   Improve the overflow check. (Ozaki Kiichi, closes #9102)
Files:      src/register.c, src/testdir/test_put.vim


*** ../vim-8.2.3600/src/register.c      2021-11-02 23:10:56.930903622 +0000
--- src/register.c      2021-11-16 12:47:56.944799820 +0000
***************
*** 1884,1901 ****
                    spaces = 0;
            }
  
!           // insert the new text
            totlen = count * (yanklen + spaces) + bd.startspaces + bd.endspaces;
            newp = alloc(totlen + oldlen + 1);
            if (newp == NULL)
                break;
            // copy part up to cursor to new line
            ptr = newp;
            mch_memmove(ptr, oldp, (size_t)bd.textcol);
            ptr += bd.textcol;
            // may insert some spaces before the new text
            vim_memset(ptr, ' ', (size_t)bd.startspaces);
            ptr += bd.startspaces;
            // insert the new text
            for (j = 0; j < count; ++j)
            {
--- 1884,1913 ----
                    spaces = 0;
            }
  
!           // Insert the new text.
!           // First check for multiplication overflow.
!           if (yanklen + spaces != 0
!                    && count > ((INT_MAX - (bd.startspaces + bd.endspaces))
!                                                       / (yanklen + spaces)))
!           {
!               emsg(_(e_resulting_text_too_long));
!               break;
!           }
! 
            totlen = count * (yanklen + spaces) + bd.startspaces + bd.endspaces;
            newp = alloc(totlen + oldlen + 1);
            if (newp == NULL)
                break;
+ 
            // copy part up to cursor to new line
            ptr = newp;
            mch_memmove(ptr, oldp, (size_t)bd.textcol);
            ptr += bd.textcol;
+ 
            // may insert some spaces before the new text
            vim_memset(ptr, ' ', (size_t)bd.startspaces);
            ptr += bd.startspaces;
+ 
            // insert the new text
            for (j = 0; j < count; ++j)
            {
***************
*** 1909,1917 ****
--- 1921,1931 ----
                    ptr += spaces;
                }
            }
+ 
            // may insert some spaces after the new text
            vim_memset(ptr, ' ', (size_t)bd.endspaces);
            ptr += bd.endspaces;
+ 
            // move the text after the cursor to the end of the line.
            mch_memmove(ptr, oldp + bd.textcol + delcount,
                                (size_t)(oldlen - bd.textcol - delcount + 1));
***************
*** 2010,2035 ****
                }
            }
  
!           do {
! #ifdef FEAT_FLOAT
!               double multlen = (double)count * (double)yanklen;
! 
                totlen = count * yanklen;
!               if ((double)totlen != multlen)
! #else
!               long multlen = count * yanklen;
! 
!               // this only works when sizeof(int) != sizeof(long)
!               totlen = multlen;
!               if (totlen != multlen)
! #endif
!               {
!                   emsg(_(e_resulting_text_too_long));
!                   break;
!               }
!               else if (totlen > 0)
!               {
                    oldp = ml_get(lnum);
                    if (lnum > start_lnum)
                    {
                        pos_T   pos;
--- 2024,2043 ----
                }
            }
  
!           if (count == 0 || yanklen == 0)
!           {
!               if (VIsual_active)
!                   lnum = end_lnum;
!           }
!           else if (count > INT_MAX / yanklen)
!               // multiplication overflow
!               emsg(_(e_resulting_text_too_long));
!           else
!           {
                totlen = count * yanklen;
!               do {
                    oldp = ml_get(lnum);
+                   oldlen = (int)STRLEN(oldp);
                    if (lnum > start_lnum)
                    {
                        pos_T   pos;
***************
*** 2040,2051 ****
                        else
                            col = MAXCOL;
                    }
!                   if (VIsual_active && col > (int)STRLEN(oldp))
                    {
                        lnum++;
                        continue;
                    }
!                   newp = alloc(STRLEN(oldp) + totlen + 1);
                    if (newp == NULL)
                        goto end;       // alloc() gave an error message
                    mch_memmove(newp, oldp, (size_t)col);
--- 2048,2059 ----
                        else
                            col = MAXCOL;
                    }
!                   if (VIsual_active && col > oldlen)
                    {
                        lnum++;
                        continue;
                    }
!                   newp = alloc(totlen + oldlen + 1);
                    if (newp == NULL)
                        goto end;       // alloc() gave an error message
                    mch_memmove(newp, oldp, (size_t)col);
***************
*** 2064,2076 ****
                        changed_cline_bef_curs();
                        curwin->w_cursor.col += (colnr_T)(totlen - 1);
                    }
!               }
!               if (VIsual_active)
!                   lnum++;
!           } while (VIsual_active && lnum <= end_lnum);
  
!           if (VIsual_active) // reset lnum to the last visual line
!               lnum--;
  
            curbuf->b_op_end = curwin->w_cursor;
            // For "CTRL-O p" in Insert mode, put cursor after last char
--- 2072,2084 ----
                        changed_cline_bef_curs();
                        curwin->w_cursor.col += (colnr_T)(totlen - 1);
                    }
!                   if (VIsual_active)
!                       lnum++;
!               } while (VIsual_active && lnum <= end_lnum);
  
!               if (VIsual_active) // reset lnum to the last visual line
!                   lnum--;
!           }
  
            curbuf->b_op_end = curwin->w_cursor;
            // For "CTRL-O p" in Insert mode, put cursor after last char
*** ../vim-8.2.3600/src/testdir/test_put.vim    2021-11-04 15:10:07.357074257 
+0000
--- src/testdir/test_put.vim    2021-11-16 12:42:27.281157120 +0000
***************
*** 149,156 ****
  endfunc
  
  func Test_very_large_count()
!   if v:sizeofint != 8
!     throw 'Skipped: only works with 64 bit ints'
    endif
  
    new
--- 149,164 ----
  endfunc
  
  func Test_very_large_count()
!   new
!   " total put-length (21474837 * 100) brings 32 bit int overflow
!   let @" = repeat('x', 100)
!   call assert_fails('norm 21474837p', 'E1240:')
!   bwipe!
! endfunc
! 
! func Test_very_large_count_64bit()
!   if v:sizeoflong < 8
!     throw 'Skipped: only works with 64 bit long ints'
    endif
  
    new
***************
*** 158,163 ****
--- 166,192 ----
    call assert_fails('norm 44444444444444p', 'E1240:')
    bwipe!
  endfunc
+ 
+ func Test_very_large_count_block()
+   new
+   " total put-length (21474837 * 100) brings 32 bit int overflow
+   call setline(1, repeat('x', 100))
+   exe "norm \<C-V>99ly"
+   call assert_fails('norm 21474837p', 'E1240:')
+   bwipe!
+ endfunc
+ 
+ func Test_very_large_count_block_64bit()
+   if v:sizeoflong < 8
+     throw 'Skipped: only works with 64 bit long ints'
+   endif
+ 
+   new
+   call setline(1, 'x')
+   exe "norm \<C-V>y"
+   call assert_fails('norm 44444444444444p', 'E1240:')
+   bwipe!
+ endfunc
  
  func Test_put_above_first_line()
    new
*** ../vim-8.2.3600/src/version.c       2021-11-16 11:53:09.453121747 +0000
--- src/version.c       2021-11-16 12:44:58.577003578 +0000
***************
*** 759,760 ****
--- 759,762 ----
  {   /* Add new patch number below this line */
+ /**/
+     3601,
  /**/

-- 
ARTHUR:  Shut up!  Will you shut up!
DENNIS:  Ah, now we see the violence inherent in the system.
ARTHUR:  Shut up!
DENNIS:  Oh!  Come and see the violence inherent in the system!
         HELP! HELP!  I'm being repressed!
                                  The Quest for the Holy Grail (Monty Python)

 /// 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/20211116125116.2A9511C4F3A%40moolenaar.net.

Raspunde prin e-mail lui