To: vim_dev@googlegroups.com Subject: Patch 8.2.3659 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 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 -- Bram@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 ///