diff options
author | ZyX <kp-pav@yandex.ru> | 2018-04-01 21:29:47 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2018-04-01 21:29:47 +0300 |
commit | dd1b493f7560244162f4051443fb42dabaee0254 (patch) | |
tree | 26b62f2e8ddbfeae53161dc520512bfd0e436e71 /src | |
parent | f5373e2cdc6693a3353a37dd0652694834709739 (diff) | |
download | rneovim-dd1b493f7560244162f4051443fb42dabaee0254.tar.gz rneovim-dd1b493f7560244162f4051443fb42dabaee0254.tar.bz2 rneovim-dd1b493f7560244162f4051443fb42dabaee0254.zip |
shada: Fix some memory leaks and completely ignore numbered mark names
Problems:
- In two places in shada_read_when_writing() memory just was not freed. Both
places were verified to cause test failures.
- Numbered marks got assigned incorrect (off-by-one compared to position in the
array) numbers in replace_numbered_mark.
- It was possible to have non-continuously populated array of numbered marks
which messed up code for merging them.
(Note about tests: marks with additional data are always compared different when
merging, that caused some confusion regarding why test did not work the way
I expected.)
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/shada.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 7b930d9f09..fd095b1ade 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -2255,6 +2255,7 @@ static inline ShaDaWriteResult shada_read_when_writing( entry.data.filemark.mark) && strcmp(wms_entry.data.filemark.fname, entry.data.filemark.fname) == 0) { + shada_free_shada_entry(&entry); processed_mark = true; break; } @@ -2262,6 +2263,8 @@ static inline ShaDaWriteResult shada_read_when_writing( processed_mark = true; if (i < ARRAY_SIZE(wms->numbered_marks)) { replace_numbered_mark(wms, i, pfs_entry); + } else { + shada_free_shada_entry(&entry); } break; } @@ -2539,7 +2542,7 @@ static inline void replace_numbered_mark(WriteMergerState *const wms, } for (size_t i = idx; i < ARRAY_SIZE(wms->numbered_marks) - 1; i++) { if (wms->numbered_marks[i].data.type == kSDItemGlobalMark) { - wms->numbered_marks[i].data.data.filemark.name = '0' + (char)i; + wms->numbered_marks[i].data.data.filemark.name = '0' + (char)i + 1; } } memmove(wms->numbered_marks + idx + 1, wms->numbered_marks + idx, @@ -2781,6 +2784,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, // Initialize global marks if (dump_global_marks) { const void *global_mark_iter = NULL; + size_t digit_mark_idx = 0; do { char name = NUL; xfmark_T fm; @@ -2803,24 +2807,26 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, } fname = (const char *) buf->b_ffname; } - *(ascii_isdigit(name) - ? &wms->numbered_marks[name - '0'] - : &wms->global_marks[mark_global_index(name)]) = ( - (PossiblyFreedShadaEntry) { - .can_free_entry = false, - .data = { - .type = kSDItemGlobalMark, - .timestamp = fm.fmark.timestamp, - .data = { - .filemark = { - .mark = fm.fmark.mark, - .name = name, - .additional_data = fm.fmark.additional_data, - .fname = (char *)fname, - } - } - }, - }); + const PossiblyFreedShadaEntry pf_entry = { + .can_free_entry = false, + .data = { + .type = kSDItemGlobalMark, + .timestamp = fm.fmark.timestamp, + .data = { + .filemark = { + .mark = fm.fmark.mark, + .name = name, + .additional_data = fm.fmark.additional_data, + .fname = (char *)fname, + } + } + }, + }; + if (ascii_isdigit(name)) { + replace_numbered_mark(wms, digit_mark_idx++, pf_entry); + } else { + wms->global_marks[mark_global_index(name)] = pf_entry; + } } while (global_mark_iter != NULL); } |