ngollan wrote:

> When pasting a high unicode character (>uFFFF) into vim, the program
> sometimes crashes from a SIGFPE.
>
> I'm running vim from Debian testing on amd64.
>
> ===== Example character:
> http://www.fileformat.info/info/unicode/char/1f638/index.htm

Hi

I can reproduce it with Vim-7.3.364 on Linux. Just opening a
file containing Unicode character 0x1f638 makes Vim crash.

I see that the binary search fails to find a range in function utf_convert(...):

vim/src/mbytes.c:

2761 utf_convert(a, table, tableSize)
2762     int                 a;
2763     convertStruct       table[];
2764     int                 tableSize;
2765 {
2766     int start, mid, end; /* indices into table */
2767
2768     start = 0;
2769     end = tableSize / sizeof(convertStruct);
2770     while (start < end)
2771     {
2772         /* need to search further */
2773         mid = (end + start) /2;
2774         if (table[mid].rangeEnd < a)
2775             start = mid + 1;
2776         else
2777             end = mid;
2778     }
2779     if (table[start].rangeStart <= a && a <= table[start].rangeEnd
2780             && (a - table[start].rangeStart) % table[start].step == 0)
2781         return (a + table[start].offset);
2782     else
2783         return a;
2784 }

The start, mid, end variables in utf_convert evolve as follow
during the binary search:

start=0 mid=78 end=156
start=79 mid=117 end=156
start=118 mid=137 end=156
start=138 mid=147 end=156
start=148 mid=152 end=156
start=153 mid=154 end=156
start=155 mid=155 end=156
start=156 mid=155 end=156

Then at line mbytes.c:2779, table[start] it used
which accesses beyond the end of foldCase[] array.

Interestingly, Valgrind memory checker does
not detect this (since it's an overflow in a
global variable) but the address-sanitizer tool
available at...
  http://code.google.com/p/address-sanitizer/
... does detect it and says:

READ of size 4 at 0x000000afc440 thread T0
    #0 0x5e63c2 in utf_convert mbyte.c:0
    #1 0x670dbf in vim_regexec_both regexp.c:0
    #2 0x67110c in vim_regexec_nl ??:0
    #3 0x4bdb86 in eval4 eval.c:0
    #4 0x4bcc94 in eval3 eval.c:0
    #5 0x4bc844 in eval2 eval.c:0
    #6 0x47b7be in eval1 eval.c:0
    #7 0x47af5e in eval0 eval.c:0
    #8 0x47aa29 in eval_to_bool ??:0
    #9 0x50f644 in ex_if ??:0
    #10 0x4efc7a in do_one_cmd ex_docmd.c:0
    #11 0x4e9383 in do_cmdline ??:0
    #12 0x4e6253 in do_source ??:0
    #13 0x4e506a in do_in_runtimepath ??:0
    #14 0x4efc7a in do_one_cmd ex_docmd.c:0
    #15 0x4e9383 in do_cmdline ??:0
    #16 0x54340e in apply_autocmds_group fileio.c:0
    #17 0x53361f in apply_autocmds_exarg fileio.c:0
    #18 0x532d94 in readfile ??:0
    #19 0x4321cc in open_buffer ??:0
    #20 0x7bc94a in create_windows main.c:0
    #21 0x7b7582 in main ??:0
    #22 0x7faffcdaed8e in __libc_start_main
/build/buildd/eglibc-2.12.1/csu/libc-start.c:258
    #23 0x431e19 in _start ??:0
0x000000afc440 is located 0 bytes to the right of global variable
'foldCase' (0xafba80) of size 2496

Attached patch fixes the crash.

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
diff -r 749c0a60b745 src/mbyte.c
--- a/src/mbyte.c	Thu Dec 01 20:59:21 2011 +0100
+++ b/src/mbyte.c	Tue Dec 06 16:28:08 2011 +0100
@@ -2776,7 +2776,8 @@
 	else
 	    end = mid;
     }
-    if (table[start].rangeStart <= a && a <= table[start].rangeEnd
+    if (start < tableSize / sizeof(convertStruct)
+	    && table[start].rangeStart <= a && a <= table[start].rangeEnd
 	    && (a - table[start].rangeStart) % table[start].step == 0)
 	return (a + table[start].offset);
     else

Raspunde prin e-mail lui