From 2ea619c10b28f908279832f87fb30121aaca7f5a Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 18 Jul 2018 21:14:15 -0400 Subject: vim-patch:8.0.1503: access memory beyond end of string Problem: Access memory beyond end of string. (Coverity) Solution: Keep allocated memory in separate pointer. Avoid outputting the NUL character. https://github.com/vim/vim/commit/cdd09aa51a8d34bb384460af4f91026dbff5bf48 --- src/nvim/hardcopy.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index b3a9eabdb8..70332fec86 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -2891,6 +2891,7 @@ int mch_print_text_out(char_u *p, size_t len) double next_pos; int in_ascii; int half_width; + char_u *tofree = NULL; char_width = prt_char_width; @@ -2993,23 +2994,20 @@ int mch_print_text_out(char_u *p, size_t len) } if (prt_do_conv) { - /* Convert from multi-byte to 8-bit encoding */ - p = string_convert(&prt_conv, p, &len); - if (p == NULL) - p = (char_u *)xstrdup(""); + // Convert from multi-byte to 8-bit encoding + tofree = p = string_convert(&prt_conv, p, &len); } if (prt_out_mbyte) { - /* Multi-byte character strings are represented more efficiently as hex - * strings when outputting clean 8 bit PS. - */ - do { + // Multi-byte character strings are represented more efficiently as hex + // strings when outputting clean 8 bit PS. + while (len-- > 0) { ch = prt_hexchar[(unsigned)(*p) >> 4]; ga_append(&prt_ps_buffer, (char)ch); ch = prt_hexchar[(*p) & 0xf]; ga_append(&prt_ps_buffer, (char)ch); p++; - } while (--len); + } } else { /* Add next character to buffer of characters to output. * Note: One printed character may require several PS characters to @@ -3043,9 +3041,8 @@ int mch_print_text_out(char_u *p, size_t len) ga_append(&prt_ps_buffer, (char)ch); } - /* Need to free any translated characters */ - if (prt_do_conv) - xfree(p); + // Need to free any translated characters + xfree(tofree); prt_text_run += char_width; prt_pos_x += char_width; -- cgit From 8441af37d84147f1b32d91ed9a496a57472861ef Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 19 Jul 2018 12:16:21 -0400 Subject: vim-patch:8.1.0056: crash when using :hardcopy with illegal byte Problem: Crash when using :hardcopy with illegal byte. Solution: Check for string_convert() returning NULL. (Dominique Pelle) https://github.com/vim/vim/commit/43dee181f596c81b99e200b6cdfeb02ecfed42c8 --- src/nvim/hardcopy.c | 7 ++++++- src/nvim/testdir/test_hardcopy.vim | 29 ++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index 70332fec86..972ccbb811 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -2882,8 +2882,9 @@ void mch_print_start_line(int margin, int page_line) prt_half_width = FALSE; } -int mch_print_text_out(char_u *p, size_t len) +int mch_print_text_out(char_u *textp, size_t len) { + char_u *p = textp; int need_break; char_u ch; char_u ch_buff[8]; @@ -2996,6 +2997,10 @@ int mch_print_text_out(char_u *p, size_t len) if (prt_do_conv) { // Convert from multi-byte to 8-bit encoding tofree = p = string_convert(&prt_conv, p, &len); + if (p == NULL) { + p = (char_u *)""; + len = 0; + } } if (prt_out_mbyte) { diff --git a/src/nvim/testdir/test_hardcopy.vim b/src/nvim/testdir/test_hardcopy.vim index f630556bef..ced13b107c 100644 --- a/src/nvim/testdir/test_hardcopy.vim +++ b/src/nvim/testdir/test_hardcopy.vim @@ -63,12 +63,27 @@ func Test_with_syntax() endfunc func Test_fname_with_spaces() - if has('postscript') - split t\ e\ s\ t.txt - call setline(1, ['just', 'some', 'text']) - hardcopy > %.ps - call assert_true(filereadable('t e s t.txt.ps')) - call delete('t e s t.txt.ps') - bwipe! + if !has('postscript') + return + endif + split t\ e\ s\ t.txt + call setline(1, ['just', 'some', 'text']) + hardcopy > %.ps + call assert_true(filereadable('t e s t.txt.ps')) + call delete('t e s t.txt.ps') + bwipe! +endfunc + +func Test_illegal_byte() + if !has('postscript') || &enc != 'utf-8' + return endif + new + " conversion of 0xff will fail, this used to cause a crash + call setline(1, "\xff") + hardcopy >Xpstest + + bwipe! + call delete('Xpstest') endfunc + -- cgit From 588e86bda668f34ef75193f367f80d967ff3ad92 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 19 Jul 2018 12:33:03 -0400 Subject: hardcopy: refactor mch_print_text_out() Combine variable declaration and initialization to add const. --- src/nvim/hardcopy.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index 972ccbb811..e1eb8f0251 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -2882,19 +2882,13 @@ void mch_print_start_line(int margin, int page_line) prt_half_width = FALSE; } -int mch_print_text_out(char_u *textp, size_t len) +int mch_print_text_out(char_u *const textp, size_t len) { char_u *p = textp; - int need_break; char_u ch; char_u ch_buff[8]; - double char_width; - double next_pos; - int in_ascii; - int half_width; char_u *tofree = NULL; - - char_width = prt_char_width; + double char_width = prt_char_width; /* Ideally VIM would create a rearranged CID font to combine a Roman and * CJKV font to do what VIM is doing here - use a Roman font for characters @@ -2904,7 +2898,7 @@ int mch_print_text_out(char_u *textp, size_t len) * years! If they ever do, a lot of this code will disappear. */ if (prt_use_courier) { - in_ascii = (len == 1 && *p < 0x80); + const bool in_ascii = (len == 1 && *p < 0x80); if (prt_in_ascii) { if (!in_ascii) { /* No longer in ASCII range - need to switch font */ @@ -2920,9 +2914,10 @@ int mch_print_text_out(char_u *textp, size_t len) } } if (prt_out_mbyte) { - half_width = ((*mb_ptr2cells)(p) == 1); - if (half_width) + const bool half_width = ((*mb_ptr2cells)(p) == 1); + if (half_width) { char_width /= 2; + } if (prt_half_width) { if (!half_width) { prt_half_width = FALSE; @@ -3053,12 +3048,13 @@ int mch_print_text_out(char_u *textp, size_t len) prt_pos_x += char_width; // The downside of fp - use relative error on right margin check - next_pos = prt_pos_x + prt_char_width; - need_break = ((next_pos > prt_right_margin) - && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5))); + const double next_pos = prt_pos_x + prt_char_width; + const bool need_break = (next_pos > prt_right_margin) + && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5)); - if (need_break) + if (need_break) { prt_flush_buffer(); + } return need_break; } -- cgit