When Vim crashes it may run out of stack while executing autocommands. Patch
to not run autocommands when leaving Vim? (James Vega, 2010 May 23)
+Invalid memory access when deleting funcref variable. Patch by Lech Lorens,
+2010 May 25.
+
Cursor positioning wrong with 0x200e character. (John Becket, 2010 May 6)
E315 when trying to change a file in FileChangedRO autocommand event.
Wait until window is gone with EnumWindows (see os_win32.c).
Patches to include:
- Persistent undo bugs / fixes:
- - Add undofile(name): get undo file name for buffer "name".
+ - Patch not to allocate extra byte in U_ALLOC_LINE() (Dominique, 2010 May
+ 25)
+ - Remove the old code when U_USE_MALLOC is not defined?
- When there is no undo info (undolevels negative), delete the undo file.
+ - Need to check all values for evil manipulation.
+ - Add undofile(name): get undo file name for buffer "name".
- Extend test62 for gettabvar() and settabvar(). (Yegappan Lakshmanan, 2010
May 23)
- Also crypt the undo file.
static void unserialize_pos __ARGS((pos_T *pos, FILE *fp));
static void unserialize_visualinfo __ARGS((visualinfo_T *info, FILE *fp));
static char_u *u_get_undo_file_name __ARGS((char_u *, int reading));
+static void u_free_uhp __ARGS((u_header_T *uhp));
static int serialize_uep __ARGS((u_entry_T *uep, FILE *fp));
static void serialize_pos __ARGS((pos_T pos, FILE *fp));
static void serialize_visualinfo __ARGS((visualinfo_T info, FILE *fp));
time_t seq_time;
int i, j;
int c;
- short found_first_uep = 0;
char_u **array;
char_u *line;
- u_entry_T *uep, *last_uep, *nuep;
+ u_entry_T *uep, *last_uep;
u_header_T *uhp;
u_header_T **uhp_table = NULL;
char_u read_hash[UNDO_HASH_SIZE];
seq_cur = get4c(fp);
seq_time = get4c(fp);
+ if (num_head < 0)
+ num_head = 0;
+
/* uhp_table will store the freshly created undo headers we allocate
* until we insert them into curbuf. The table remains sorted by the
* sequence numbers of the headers. */
c = get2c(fp);
while (c == UF_HEADER_MAGIC)
{
- found_first_uep = 0;
+ if (num_read_uhps >= num_head)
+ {
+ EMSG2(_("E831 Undo file corruption: num_head: %s"), file_name);
+ u_free_uhp(uhp);
+ goto error;
+ }
+
uhp = (u_header_T *)U_ALLOC_LINE((unsigned)sizeof(u_header_T));
if (uhp == NULL)
goto error;
{
uep = (u_entry_T *)U_ALLOC_LINE((unsigned)sizeof(u_entry_T));
if (uep == NULL)
+ {
+ u_free_uhp(uhp);
goto error;
+ }
vim_memset(uep, 0, sizeof(u_entry_T));
+ if (last_uep == NULL)
+ uhp->uh_entry = uep;
+ else
+ last_uep->ue_next = uep;
+ last_uep = uep;
+
uep->ue_top = get4c(fp);
uep->ue_bot = get4c(fp);
uep->ue_lcount = get4c(fp);
uep->ue_next = NULL;
array = (char_u **)U_ALLOC_LINE(
(unsigned)(sizeof(char_u *) * uep->ue_size));
+ if (array == NULL)
+ {
+ u_free_uhp(uhp);
+ goto error;
+ }
+ vim_memset(array, 0, sizeof(char_u *) * uep->ue_size);
+ uep->ue_array = array;
+
for (i = 0; i < uep->ue_size; i++)
{
line_len = get4c(fp);
/* U_ALLOC_LINE provides an extra byte for the NUL terminator.*/
line = (char_u *)U_ALLOC_LINE(
- (unsigned) (sizeof(char_u) * line_len));
+ (unsigned)(sizeof(char_u) * line_len));
if (line == NULL)
+ {
+ u_free_uhp(uhp);
goto error;
+ }
for (j = 0; j < line_len; j++)
- {
line[j] = getc(fp);
- }
line[j] = '\0';
array[i] = line;
}
- uep->ue_array = array;
- if (found_first_uep == 0)
- {
- uhp->uh_entry = uep;
- found_first_uep = 1;
- }
- else
- {
- last_uep->ue_next = uep;
- }
- last_uep = uep;
}
/* Insertion sort the uhp into the table by its uh_seq. This is
* required because, while the number of uhps is limited to
- * num_heads, and the uh_seq order is monotonic with respect to
+ * num_head, and the uh_seq order is monotonic with respect to
* creation time, the starting uh_seq can be > 0 if any undolevel
* culling was done at undofile write time, and there can be uh_seq
* gaps in the uhps.
if (num_read_uhps - i - 1 > 0)
{
memmove(uhp_table + i + 2, uhp_table + i + 1,
- (num_read_uhps - i - 1) * sizeof(u_header_T *));
+ (num_read_uhps - i - 1) * sizeof(u_header_T *));
}
uhp_table[i + 1] = uhp;
break;
{
EMSG2(_("E826 Undo file corruption: duplicate uh_seq: %s"),
file_name);
+ u_free_uhp(uhp);
goto error;
}
}
if (uhp_table != NULL)
{
for (i = 0; i < num_head; i++)
- {
if (uhp_table[i] != NULL)
- {
- uep = uhp_table[i]->uh_entry;
- while (uep != NULL)
- {
- nuep = uep->ue_next;
- u_freeentry(uep, uep->ue_size);
- uep = nuep;
- }
- U_FREE_LINE(uhp_table[i]);
- }
- }
+ u_free_uhp(uhp_table[i]);
U_FREE_LINE(uhp_table);
}
return;
}
+ static void
+u_free_uhp(uhp)
+ u_header_T *uhp;
+{
+ u_entry_T *nuep;
+ u_entry_T *uep;
+
+ uep = uhp->uh_entry;
+ while (uep != NULL)
+ {
+ nuep = uep->ue_next;
+ u_freeentry(uep, uep->ue_size);
+ uep = nuep;
+ }
+ U_FREE_LINE(uhp);
+}
+
/*
* Serialize "uep" to "fp".
*/