Hi The attached bug.vim script causes a crash in Vim-7.4.2343:
$ vim -u NONE -N -S bug.vim Vim: Caught deadly signal SEGV Segmentation fault (core dumped) The crash was introduced by recent patch Vim-7.4.2326: === commit d5824ce1b5491df7d2eb0b66189d366fa67b4585 Author: Bram Moolenaar <b...@vim.org> Date: Sun Sep 4 20:35:01 2016 +0200 patch 7.4.2326 Problem: Illegal memory access when Visual selection starts in invalid position. (Dominique Pelle) Solution: Correct position when needed. === However, prior to this patch, it was barely better anyway because vim-7.4.2325 and older were giving ml_get internal errors on that same bug.vim script: $ vim -u NONE -N -S bug.vim Error detected while processing /tmp/vim/src/c.vim: line 6: E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 E315: ml_get: invalid lnum: 2 Press ENTER or type command to continue Looking at the crash in gdb... Program received signal SIGSEGV, Segmentation fault. strlen () at ../sysdeps/x86_64/strlen.S:106 106 ../sysdeps/x86_64/strlen.S: No such file or directory. (gdb) bt #0 strlen () at ../sysdeps/x86_64/strlen.S:106 #1 0x00000000005505e4 in do_put (regname=0, dir=1, count=1, flags=0) at ops.c:3651 #2 0x000000000053ffa2 in nv_put (cap=0x7fffffffc1f8) at normal.c:9347 #3 0x000000000053488b in normal_cmd (oap=0x7fffffffc268, toplevel=1) at normal.c:1149 #4 0x0000000000494ed7 in exec_normal (was_typed=0) at ex_docmd.c:10250 #5 0x0000000000494e0b in exec_normal_cmd (cmd=0x950b75 "yp", remap=0, silent=0) at ex_docmd.c:10233 #6 0x0000000000494cca in ex_normal (eap=0x7fffffffc7c0) at ex_docmd.c:10142 #7 0x000000000048d1e8 in do_one_cmd (cmdlinep=0x7fffffffcf28, sourcing=1, cstack=0x7fffffffca70, fgetline=0x4861e0 <getsourceline>, cookie=0x7fffffffd0e0) at ex_docmd.c:2962 #8 0x00000000004887fd in do_cmdline (cmdline=0x950a60 "new", fgetline=0x4861e0 <getsourceline>, cookie=0x7fffffffd0e0, flags=7) at ex_docmd.c:1110 #9 0x0000000000485e28 in do_source (fname=0x92ad33 "c.vim", check_other=0, is_vimrc=0) at ex_cmds2.c:4110 #10 0x00000000004853ee in cmd_source (fname=0x92ad33 "c.vim", eap=0x7fffffffd540) at ex_cmds2.c:3723 #11 0x000000000048544c in ex_source (eap=0x7fffffffd540) at ex_cmds2.c:3698 #12 0x000000000048d1e8 in do_one_cmd (cmdlinep=0x7fffffffdca8, sourcing=1, cstack=0x7fffffffd7f0, fgetline =0x0, cookie=0x0) at ex_docmd.c:2962 #13 0x00000000004887fd in do_cmdline (cmdline=0x90af80 "so c.vim", fgetline=0x0, cookie=0x0, flags=11) at ex_docmd.c:1110 #14 0x00000000004896ba in do_cmdline_cmd (cmd=0x90af80 "so c.vim") at ex_docmd.c:715 #15 0x000000000066d528 in exe_commands (parmp=0x8fae38 <params>) at main.c:2896 #16 0x000000000066bfb1 in vim_main2 () at main.c:781 #17 0x0000000000669892 in main (argc=6, argv=0x7fffffffdea8) at main.c:415 (gdb) up #1 0x00000000005505e4 in do_put (regname=0, dir=1, count=1, flags=0) at ops.c:3651 3650│ 3651├> yanklen = (int)STRLEN(y_array[i]); 3652│ (gdb) p i $5 = 1 (gdb) p y_size $6 = 2 y_array[...] content is inconsistent with y_size. y_array[...] and y_size were set in ops.c at: 2976 y_current->y_size = yanklines; 2977 y_current->y_type = yanktype; /* set the yank register type */ 2978 y_current->y_width = 0; 2979 y_current->y_array = (char_u **)lalloc_clear((long_u)(sizeof(char_u *) * 2980 yanklines), TRUE); And y_current->y_array[..] was populated when calling yank_copy_line at line ops.c:3009: 3003 for ( ; lnum <= yankendlnum; lnum++, y_idx++) 3004 { 3005 switch (y_current->y_type) 3006 { 3007 case MBLOCK: 3008 block_prep(oap, &bd, lnum, FALSE); 3009 if (yank_copy_line(&bd, y_idx) == FAIL) 3010 goto fail; 3011 break; Loop at ops.c only loops from lnum=1 to yankendlnum=1 so only y_current->y_array[0] gets initialized when calling yank_copy_line() at line 3009. yankendlnum and yanklines were initialized at: 2924 long yanklines = oap->line_count; 2925 linenr_T yankendlnum = oap->end.lnum; At ops.c:2932, I could see: [ops.c:2932] oap->start.lnum=1 oap->end.lnum=1 opa->line_count=2 This does not look consistent: line_count should not be 2 if oap->start.lnum is 1 and opa->end.lnum are both 1. Attached patch fixes it, but please check because I find this code complicated. Bug was found using afl-fuzz. Regards Dominique -- -- 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. For more options, visit https://groups.google.com/d/optout.
diff --git a/src/normal.c b/src/normal.c index edaa740..2c9a365 100644 --- a/src/normal.c +++ b/src/normal.c @@ -9454,6 +9454,7 @@ get_op_vcol( { check_pos(curwin->w_buffer, &oap->end); mb_adjustpos(curwin->w_buffer, &oap->end); + oap->line_count = oap->end.lnum - oap->start.lnum + 1; } #endif
bug.vim
Description: Binary data