mirror of
https://github.com/neovim/neovim.git
synced 2025-09-17 16:58:17 +00:00
shada: When reading marks or registers, free items when set fails
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user