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