Patch 8.2.3659
Problem:    Integer overflow with large line number.
Solution:   Check for overflow. (closes #9202)
Files:      src/errors.h, src/ex_docmd.c, src/testdir/test_excmd.vim
            src/normal.c, src/testdir/test_normal.vim


*** ../vim-8.2.3658/src/errors.h        2021-11-22 21:58:37.918668436 +0000
--- src/errors.h        2021-11-24 11:43:29.642462961 +0000
***************
*** 688,690 ****
--- 688,692 ----
        INIT(= N_("E1245: Cannot expand <sfile> in a Vim9 function"));
  EXTERN char e_cannot_find_variable_to_unlock_str[]
        INIT(= N_("E1246: Cannot find variable to (un)lock: %s"));
+ EXTERN char e_line_number_out_of_range[]
+       INIT(= N_("E1247: Line number out of range"));
*** ../vim-8.2.3658/src/ex_docmd.c      2021-11-19 11:59:04.927685669 +0000
--- src/ex_docmd.c      2021-11-24 11:51:30.452132000 +0000
***************
*** 4380,4386 ****
--- 4380,4393 ----
            if (!VIM_ISDIGIT(*cmd))     // '+' is '+1', but '+0' is not '+1'
                n = 1;
            else
+           {
                n = getdigits(&cmd);
+               if (n == MAXLNUM)
+               {
+                   emsg(_(e_line_number_out_of_range));
+                   goto error;
+               }
+           }
  
            if (addr_type == ADDR_TABS_RELATIVE)
            {
***************
*** 4398,4410 ****
                // Relative line addressing, need to adjust for folded lines
                // now, but only do it after the first address.
                if (addr_type == ADDR_LINES && (i == '-' || i == '+')
!                       && address_count >= 2)
                    (void)hasFolding(lnum, NULL, &lnum);
  #endif
                if (i == '-')
                    lnum -= n;
                else
                    lnum += n;
            }
        }
      } while (*cmd == '/' || *cmd == '?');
--- 4405,4424 ----
                // Relative line addressing, need to adjust for folded lines
                // now, but only do it after the first address.
                if (addr_type == ADDR_LINES && (i == '-' || i == '+')
!                                                        && address_count >= 2)
                    (void)hasFolding(lnum, NULL, &lnum);
  #endif
                if (i == '-')
                    lnum -= n;
                else
+               {
+                   if (n >= LONG_MAX - lnum)
+                   {
+                       emsg(_(e_line_number_out_of_range));
+                       goto error;
+                   }
                    lnum += n;
+               }
            }
        }
      } while (*cmd == '/' || *cmd == '?');
*** ../vim-8.2.3658/src/testdir/test_excmd.vim  2021-11-21 11:35:59.456938797 
+0000
--- src/testdir/test_excmd.vim  2021-11-24 11:57:22.618921533 +0000
***************
*** 655,658 ****
--- 655,670 ----
    call assert_equal('1+1', getreg('=', 1))
  endfunc
  
+ func Test_address_line_overflow()
+   if v:sizeoflong < 8
+     throw 'Skipped: only works with 64 bit long ints'
+   endif
+   new
+   call setline(1, 'text')
+   call assert_fails('|.44444444444444444444444', 'E1247:')
+   call assert_fails('|.9223372036854775806', 'E1247:')
+   bwipe!
+ endfunc
+ 
+ 
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.3658/src/normal.c        2021-11-22 14:16:05.113603052 +0000
--- src/normal.c        2021-11-24 12:11:09.513125835 +0000
***************
*** 630,639 ****
                del_from_showcmd(4);    // delete the digit and ~@%
  #endif
            }
            else
                ca.count0 = ca.count0 * 10 + (c - '0');
!           if (ca.count0 < 0)      // overflow
!               ca.count0 = 999999999L;
  #ifdef FEAT_EVAL
            // Set v:count here, when called from main() and not a stuffed
            // command, so that v:count can be used in an expression mapping
--- 630,643 ----
                del_from_showcmd(4);    // delete the digit and ~@%
  #endif
            }
+           else if (ca.count0 >= 999999999L)
+           {
+               ca.count0 = 999999999L;
+           }
            else
+           {
                ca.count0 = ca.count0 * 10 + (c - '0');
!           }
  #ifdef FEAT_EVAL
            // Set v:count here, when called from main() and not a stuffed
            // command, so that v:count can be used in an expression mapping
***************
*** 700,710 ****
         * multiplied.
         */
        if (ca.count0)
!           ca.count0 *= ca.opcount;
        else
            ca.count0 = ca.opcount;
-       if (ca.count0 < 0)          // overflow
-           ca.count0 = 999999999L;
      }
  
      /*
--- 704,717 ----
         * multiplied.
         */
        if (ca.count0)
!       {
!           if (ca.opcount >= 999999999L / ca.count0)
!               ca.count0 = 999999999L;
!           else
!               ca.count0 *= ca.opcount;
!       }
        else
            ca.count0 = ca.opcount;
      }
  
      /*
*** ../vim-8.2.3658/src/testdir/test_normal.vim 2021-11-22 14:16:05.117603051 
+0000
--- src/testdir/test_normal.vim 2021-11-24 12:15:56.468635073 +0000
***************
*** 3519,3522 ****
--- 3519,3543 ----
    bw!
  endfunc
  
+ func Test_normal_count_out_of_range()
+   new
+   call setline(1, 'text')
+   normal 44444444444|
+   call assert_equal(999999999, v:count)
+   normal 444444444444|
+   call assert_equal(999999999, v:count)
+   normal 4444444444444|
+   call assert_equal(999999999, v:count)
+   normal 4444444444444444444|
+   call assert_equal(999999999, v:count)
+ 
+   normal 9y99999999|
+   call assert_equal(899999991, v:count)
+   normal 10y99999999|
+   call assert_equal(999999999, v:count)
+   normal 44444444444y44444444444|
+   call assert_equal(999999999, v:count)
+   bwipe!
+ endfunc
+ 
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.3658/src/version.c       2021-11-24 11:18:03.742223158 +0000
--- src/version.c       2021-11-24 11:44:26.134427584 +0000
***************
*** 759,760 ****
--- 759,762 ----
  {   /* Add new patch number below this line */
+ /**/
+     3659,
  /**/

-- 
Biting someone with your natural teeth is "simple assault," while biting
someone with your false teeth is "aggravated assault."
                [real standing law in Louisana, 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/20211124121824.CF36B1C3DF9%40moolenaar.net.

Raspunde prin e-mail lui