lib: fix bookkeeping for libreadline malloc()s

When libreadline is used, we mistakenly mix in strdup() done in
libreadline with Quagga's lib/memory bookkeeping/counting, leading to
counter underflows on MTYPE_TMP.

Signed-off-by: Lou Berger <lberger@labn.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from commit 672900382d47137638086bd8351b2678f589a546)

Conflicts:
	lib/command.c
This commit is contained in:
Lou Berger 2016-01-12 13:41:46 -05:00 committed by vivek
parent f5bb8cfa5b
commit cde9f10117
3 changed files with 31 additions and 17 deletions

View File

@ -2349,7 +2349,7 @@ cmd_complete_sort(vector matchvec)
/* Command line completion support. */ /* Command line completion support. */
static char ** static char **
cmd_complete_command_real (vector vline, struct vty *vty, int *status) cmd_complete_command_real (vector vline, struct vty *vty, int *status, int islib)
{ {
unsigned int i; unsigned int i;
vector cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node)); vector cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
@ -2435,11 +2435,12 @@ cmd_complete_command_real (vector vline, struct vty *vty, int *status)
for (j = 0; j < vector_active (match_vector); j++) for (j = 0; j < vector_active (match_vector); j++)
if ((token = vector_slot (match_vector, j))) if ((token = vector_slot (match_vector, j)))
{ {
if ((string = string = cmd_entry_function (vector_slot (vline, index),
cmd_entry_function (vector_slot (vline, index), token->cmd);
token->cmd))) if (string && cmd_unique_string (matchvec, string))
if (cmd_unique_string (matchvec, string)) vector_set (matchvec, (islib != 0 ?
vector_set (matchvec, XSTRDUP (MTYPE_TMP, string)); XSTRDUP (MTYPE_TMP, string) :
strdup (string) /* rl freed */));
} }
} }
@ -2485,7 +2486,9 @@ cmd_complete_command_real (vector vline, struct vty *vty, int *status)
{ {
char *lcdstr; char *lcdstr;
lcdstr = XMALLOC (MTYPE_TMP, lcd + 1); lcdstr = (islib != 0 ?
XMALLOC (MTYPE_TMP, lcd + 1) :
malloc(lcd + 1));
memcpy (lcdstr, matchvec->index[0], lcd); memcpy (lcdstr, matchvec->index[0], lcd);
lcdstr[lcd] = '\0'; lcdstr[lcd] = '\0';
@ -2495,7 +2498,12 @@ cmd_complete_command_real (vector vline, struct vty *vty, int *status)
for (i = 0; i < vector_active (matchvec); i++) for (i = 0; i < vector_active (matchvec); i++)
{ {
if (vector_slot (matchvec, i)) if (vector_slot (matchvec, i))
{
if (islib != 0)
XFREE (MTYPE_TMP, vector_slot (matchvec, i)); XFREE (MTYPE_TMP, vector_slot (matchvec, i));
else
free (vector_slot (matchvec, i));
}
} }
vector_free (matchvec); vector_free (matchvec);
@ -2519,7 +2527,7 @@ cmd_complete_command_real (vector vline, struct vty *vty, int *status)
} }
char ** char **
cmd_complete_command (vector vline, struct vty *vty, int *status) cmd_complete_command_lib (vector vline, struct vty *vty, int *status, int islib)
{ {
char **ret; char **ret;
@ -2540,15 +2548,20 @@ cmd_complete_command (vector vline, struct vty *vty, int *status)
vector_set_index (shifted_vline, index-1, vector_lookup(vline, index)); vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
} }
ret = cmd_complete_command_real (shifted_vline, vty, status); ret = cmd_complete_command_real (shifted_vline, vty, status, islib);
vector_free(shifted_vline); vector_free(shifted_vline);
vty->node = onode; vty->node = onode;
return ret; return ret;
} }
return cmd_complete_command_real (vline, vty, status, islib);
}
return cmd_complete_command_real (vline, vty, status); char **
cmd_complete_command (vector vline, struct vty *vty, int *status)
{
return cmd_complete_command_lib (vline, vty, status, 0);
} }
/* return parent node */ /* return parent node */

View File

@ -550,6 +550,7 @@ extern vector cmd_make_strvec (const char *);
extern void cmd_free_strvec (vector); extern void cmd_free_strvec (vector);
extern vector cmd_describe_command (vector, struct vty *, int *status); extern vector cmd_describe_command (vector, struct vty *, int *status);
extern char **cmd_complete_command (vector, struct vty *, int *status); extern char **cmd_complete_command (vector, struct vty *, int *status);
extern char **cmd_complete_command_lib (vector, struct vty *, int *status, int islib);
extern const char *cmd_prompt (enum node_type); extern const char *cmd_prompt (enum node_type);
extern int command_config_read_one_line (struct vty *vty, struct cmd_element **, int use_config_node); extern int command_config_read_one_line (struct vty *vty, struct cmd_element **, int use_config_node);
extern int config_from_file (struct vty *, FILE *, unsigned int *line_num); extern int config_from_file (struct vty *, FILE *, unsigned int *line_num);

View File

@ -873,7 +873,7 @@ vty_complete_command (struct vty *vty)
if (isspace ((int) vty->buf[vty->length - 1])) if (isspace ((int) vty->buf[vty->length - 1]))
vector_set (vline, NULL); vector_set (vline, NULL);
matched = cmd_complete_command (vline, vty, &ret); matched = cmd_complete_command_lib (vline, vty, &ret, 1);
cmd_free_strvec (vline); cmd_free_strvec (vline);