diff options
author | ZyX <kp-pav@yandex.ru> | 2015-08-04 08:14:08 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2015-10-08 22:00:17 +0300 |
commit | 5b3e668f3e03e6b0142be5afdc72cb6dadd58498 (patch) | |
tree | e7c4309d327d430c05f181105a036c05d9161097 | |
parent | 07d9ab26c6526c0d9af0435f1adeb614a1b88743 (diff) | |
download | rneovim-5b3e668f3e03e6b0142be5afdc72cb6dadd58498.tar.gz rneovim-5b3e668f3e03e6b0142be5afdc72cb6dadd58498.tar.bz2 rneovim-5b3e668f3e03e6b0142be5afdc72cb6dadd58498.zip |
shada: When reading marks or registers, free items when set fails
-rw-r--r-- | src/nvim/mark.c | 18 | ||||
-rw-r--r-- | src/nvim/ops.c | 10 | ||||
-rw-r--r-- | src/nvim/shada.c | 16 |
3 files changed, 32 insertions, 12 deletions
diff --git a/src/nvim/mark.c b/src/nvim/mark.c index beb8dd6679..5afa24e621 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1343,19 +1343,22 @@ size_t mark_buffer_amount(const buf_T *const buf) /// @param[in] fm Mark to be set. /// @param[in] update If true then only set global mark if it was created /// later then existing one. -void mark_set_global(const char name, const xfmark_T fm, const bool update) +/// +/// @return true on success, false on failure. +bool mark_set_global(const char name, const xfmark_T fm, const bool update) { xfmark_T *fm_tgt = &(namedfm[mark_global_index(name)]); if (fm_tgt == &namedfm[0] - 1) { - return; + return false; } if (update && fm.fmark.timestamp < fm_tgt->fmark.timestamp) { - return; + return false; } if (fm_tgt->fmark.mark.lnum != 0) { free_xfmark(*fm_tgt); } *fm_tgt = fm; + return true; } /// Set local mark @@ -1365,7 +1368,9 @@ void mark_set_global(const char name, const xfmark_T fm, const bool update) /// @param[in] fm Mark to be set. /// @param[in] update If true then only set global mark if it was created /// later then existing one. -void mark_set_local(const char name, buf_T *const buf, +/// +/// @return true on success, false on failure. +bool mark_set_local(const char name, buf_T *const buf, const fmark_T fm, const bool update) FUNC_ATTR_NONNULL_ALL { @@ -1379,15 +1384,16 @@ void mark_set_local(const char name, buf_T *const buf, } else if (name == '.') { fm_tgt = &(buf->b_last_change); } else { - return; + return false; } if (update && fm.timestamp < fm_tgt->timestamp) { - return; + return false; } if (fm_tgt->mark.lnum != 0) { free_fmark(*fm_tgt); } *fm_tgt = fm; + return true; } /* diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 9af37df8a0..04c53d30bb 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -5368,11 +5368,17 @@ size_t op_register_amount(void) } /// Set register to a given value -void register_set(const char name, const yankreg_T reg) +/// +/// @param[in] name Register name. +/// @param[in] reg Register value. +/// +/// @return true on success, false on failure. +bool register_set(const char name, const yankreg_T reg) { int i = op_reg_index(name); if (i == -1) { - return; + return false; } y_regs[i] = reg; + return true; } diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 684a6ea62d..c91005ab9c 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1240,14 +1240,16 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) shada_free_shada_entry(&cur_entry); break; } - register_set(cur_entry.data.reg.name, (yankreg_T) { + if (!register_set(cur_entry.data.reg.name, (yankreg_T) { .y_array = (char_u **) cur_entry.data.reg.contents, .y_size = (linenr_T) cur_entry.data.reg.contents_size, .y_type = cur_entry.data.reg.type, .y_width = (colnr_T) cur_entry.data.reg.width, .timestamp = cur_entry.timestamp, .additional_data = cur_entry.data.reg.additional_data, - }); + })) { + shada_free_shada_entry(&cur_entry); + } // Do not free shada entry: its allocated memory was saved above. break; } @@ -1277,7 +1279,10 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) }, }; if (cur_entry.type == kSDItemGlobalMark) { - mark_set_global(cur_entry.data.filemark.name, fm, !force); + if (!mark_set_global(cur_entry.data.filemark.name, fm, !force)) { + shada_free_shada_entry(&cur_entry); + break; + } } else { if (force) { if (curwin->w_jumplistlen == JUMPLISTSIZE) { @@ -1400,7 +1405,10 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) .additional_data = cur_entry.data.filemark.additional_data, }; if (cur_entry.type == kSDItemLocalMark) { - mark_set_local(cur_entry.data.filemark.name, buf, fm, !force); + if (!mark_set_local(cur_entry.data.filemark.name, buf, fm, !force)) { + shada_free_shada_entry(&cur_entry); + break; + } } else { int kh_ret; (void) kh_put(bufset, cl_bufs, (uintptr_t) buf, &kh_ret); |