mirror of
https://github.com/vim/vim.git
synced 2025-09-30 04:44:14 -04:00
More strict checks for the undo file.
This commit is contained in:
@@ -4166,7 +4166,17 @@ E819 editing.txt /*E819*
|
|||||||
E82 message.txt /*E82*
|
E82 message.txt /*E82*
|
||||||
E820 editing.txt /*E820*
|
E820 editing.txt /*E820*
|
||||||
E821 options.txt /*E821*
|
E821 options.txt /*E821*
|
||||||
|
E822 undo.txt /*E822*
|
||||||
|
E823 undo.txt /*E823*
|
||||||
|
E824 undo.txt /*E824*
|
||||||
|
E825 undo.txt /*E825*
|
||||||
|
E826 undo.txt /*E826*
|
||||||
|
E827 undo.txt /*E827*
|
||||||
|
E828 undo.txt /*E828*
|
||||||
|
E829 undo.txt /*E829*
|
||||||
E83 message.txt /*E83*
|
E83 message.txt /*E83*
|
||||||
|
E830 undo.txt /*E830*
|
||||||
|
E831 undo.txt /*E831*
|
||||||
E84 windows.txt /*E84*
|
E84 windows.txt /*E84*
|
||||||
E85 options.txt /*E85*
|
E85 options.txt /*E85*
|
||||||
E86 windows.txt /*E86*
|
E86 windows.txt /*E86*
|
||||||
|
@@ -33,6 +33,9 @@ be worked on, but only if you sponsor Vim development. See |sponsor|.
|
|||||||
When Vim crashes it may run out of stack while executing autocommands. Patch
|
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)
|
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)
|
Cursor positioning wrong with 0x200e character. (John Becket, 2010 May 6)
|
||||||
|
|
||||||
E315 when trying to change a file in FileChangedRO autocommand event.
|
E315 when trying to change a file in FileChangedRO autocommand event.
|
||||||
@@ -1094,8 +1097,12 @@ Vim 7.3:
|
|||||||
Wait until window is gone with EnumWindows (see os_win32.c).
|
Wait until window is gone with EnumWindows (see os_win32.c).
|
||||||
Patches to include:
|
Patches to include:
|
||||||
- Persistent undo bugs / fixes:
|
- 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.
|
- 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
|
- Extend test62 for gettabvar() and settabvar(). (Yegappan Lakshmanan, 2010
|
||||||
May 23)
|
May 23)
|
||||||
- Also crypt the undo file.
|
- Also crypt the undo file.
|
||||||
|
@@ -267,8 +267,8 @@ Reading an existing undo file may fail for several reasons:
|
|||||||
The file text differs from when the undo file was written. This means
|
The file text differs from when the undo file was written. This means
|
||||||
the undo file cannot be used, it would corrupt the text. This also
|
the undo file cannot be used, it would corrupt the text. This also
|
||||||
happens when 'encoding' differs from when the undo file was written.
|
happens when 'encoding' differs from when the undo file was written.
|
||||||
*E825* *E826* The undo file does not contain valid contents and cannot be
|
*E825* *E826* *E831*
|
||||||
used.
|
The undo file does not contain valid contents and cannot be used.
|
||||||
*E827* The magic number at the end of the file was not found. This usually
|
*E827* The magic number at the end of the file was not found. This usually
|
||||||
means the file was truncated.
|
means the file was truncated.
|
||||||
|
|
||||||
|
85
src/undo.c
85
src/undo.c
@@ -107,6 +107,7 @@ static void u_freeentry __ARGS((u_entry_T *, long));
|
|||||||
static void unserialize_pos __ARGS((pos_T *pos, FILE *fp));
|
static void unserialize_pos __ARGS((pos_T *pos, FILE *fp));
|
||||||
static void unserialize_visualinfo __ARGS((visualinfo_T *info, 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 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 int serialize_uep __ARGS((u_entry_T *uep, FILE *fp));
|
||||||
static void serialize_pos __ARGS((pos_T pos, FILE *fp));
|
static void serialize_pos __ARGS((pos_T pos, FILE *fp));
|
||||||
static void serialize_visualinfo __ARGS((visualinfo_T info, FILE *fp));
|
static void serialize_visualinfo __ARGS((visualinfo_T info, FILE *fp));
|
||||||
@@ -835,10 +836,9 @@ u_read_undo(name, hash)
|
|||||||
time_t seq_time;
|
time_t seq_time;
|
||||||
int i, j;
|
int i, j;
|
||||||
int c;
|
int c;
|
||||||
short found_first_uep = 0;
|
|
||||||
char_u **array;
|
char_u **array;
|
||||||
char_u *line;
|
char_u *line;
|
||||||
u_entry_T *uep, *last_uep, *nuep;
|
u_entry_T *uep, *last_uep;
|
||||||
u_header_T *uhp;
|
u_header_T *uhp;
|
||||||
u_header_T **uhp_table = NULL;
|
u_header_T **uhp_table = NULL;
|
||||||
char_u read_hash[UNDO_HASH_SIZE];
|
char_u read_hash[UNDO_HASH_SIZE];
|
||||||
@@ -914,6 +914,9 @@ u_read_undo(name, hash)
|
|||||||
seq_cur = get4c(fp);
|
seq_cur = get4c(fp);
|
||||||
seq_time = get4c(fp);
|
seq_time = get4c(fp);
|
||||||
|
|
||||||
|
if (num_head < 0)
|
||||||
|
num_head = 0;
|
||||||
|
|
||||||
/* uhp_table will store the freshly created undo headers we allocate
|
/* uhp_table will store the freshly created undo headers we allocate
|
||||||
* until we insert them into curbuf. The table remains sorted by the
|
* until we insert them into curbuf. The table remains sorted by the
|
||||||
* sequence numbers of the headers. */
|
* sequence numbers of the headers. */
|
||||||
@@ -925,7 +928,13 @@ u_read_undo(name, hash)
|
|||||||
c = get2c(fp);
|
c = get2c(fp);
|
||||||
while (c == UF_HEADER_MAGIC)
|
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));
|
uhp = (u_header_T *)U_ALLOC_LINE((unsigned)sizeof(u_header_T));
|
||||||
if (uhp == NULL)
|
if (uhp == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
@@ -973,8 +982,17 @@ u_read_undo(name, hash)
|
|||||||
{
|
{
|
||||||
uep = (u_entry_T *)U_ALLOC_LINE((unsigned)sizeof(u_entry_T));
|
uep = (u_entry_T *)U_ALLOC_LINE((unsigned)sizeof(u_entry_T));
|
||||||
if (uep == NULL)
|
if (uep == NULL)
|
||||||
|
{
|
||||||
|
u_free_uhp(uhp);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
vim_memset(uep, 0, sizeof(u_entry_T));
|
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_top = get4c(fp);
|
||||||
uep->ue_bot = get4c(fp);
|
uep->ue_bot = get4c(fp);
|
||||||
uep->ue_lcount = get4c(fp);
|
uep->ue_lcount = get4c(fp);
|
||||||
@@ -982,37 +1000,35 @@ u_read_undo(name, hash)
|
|||||||
uep->ue_next = NULL;
|
uep->ue_next = NULL;
|
||||||
array = (char_u **)U_ALLOC_LINE(
|
array = (char_u **)U_ALLOC_LINE(
|
||||||
(unsigned)(sizeof(char_u *) * uep->ue_size));
|
(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++)
|
for (i = 0; i < uep->ue_size; i++)
|
||||||
{
|
{
|
||||||
line_len = get4c(fp);
|
line_len = get4c(fp);
|
||||||
/* U_ALLOC_LINE provides an extra byte for the NUL terminator.*/
|
/* U_ALLOC_LINE provides an extra byte for the NUL terminator.*/
|
||||||
line = (char_u *)U_ALLOC_LINE(
|
line = (char_u *)U_ALLOC_LINE(
|
||||||
(unsigned) (sizeof(char_u) * line_len));
|
(unsigned)(sizeof(char_u) * line_len));
|
||||||
if (line == NULL)
|
if (line == NULL)
|
||||||
|
{
|
||||||
|
u_free_uhp(uhp);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
for (j = 0; j < line_len; j++)
|
for (j = 0; j < line_len; j++)
|
||||||
{
|
|
||||||
line[j] = getc(fp);
|
line[j] = getc(fp);
|
||||||
}
|
|
||||||
line[j] = '\0';
|
line[j] = '\0';
|
||||||
array[i] = line;
|
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
|
/* Insertion sort the uhp into the table by its uh_seq. This is
|
||||||
* required because, while the number of uhps is limited to
|
* 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
|
* 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
|
* culling was done at undofile write time, and there can be uh_seq
|
||||||
* gaps in the uhps.
|
* gaps in the uhps.
|
||||||
@@ -1028,7 +1044,7 @@ u_read_undo(name, hash)
|
|||||||
if (num_read_uhps - i - 1 > 0)
|
if (num_read_uhps - i - 1 > 0)
|
||||||
{
|
{
|
||||||
memmove(uhp_table + i + 2, uhp_table + i + 1,
|
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;
|
uhp_table[i + 1] = uhp;
|
||||||
break;
|
break;
|
||||||
@@ -1037,6 +1053,7 @@ u_read_undo(name, hash)
|
|||||||
{
|
{
|
||||||
EMSG2(_("E826 Undo file corruption: duplicate uh_seq: %s"),
|
EMSG2(_("E826 Undo file corruption: duplicate uh_seq: %s"),
|
||||||
file_name);
|
file_name);
|
||||||
|
u_free_uhp(uhp);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1105,19 +1122,8 @@ error:
|
|||||||
if (uhp_table != NULL)
|
if (uhp_table != NULL)
|
||||||
{
|
{
|
||||||
for (i = 0; i < num_head; i++)
|
for (i = 0; i < num_head; i++)
|
||||||
{
|
|
||||||
if (uhp_table[i] != NULL)
|
if (uhp_table[i] != NULL)
|
||||||
{
|
u_free_uhp(uhp_table[i]);
|
||||||
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_LINE(uhp_table);
|
U_FREE_LINE(uhp_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1129,6 +1135,23 @@ theend:
|
|||||||
return;
|
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".
|
* Serialize "uep" to "fp".
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user