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.