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
 

Attachment: bug.vim
Description: Binary data

Raspunde prin e-mail lui