summaryrefslogtreecommitdiffstats
path: root/lib/command.c
diff options
context:
space:
mode:
authorLou Berger <lberger@labn.net>2016-01-12 13:41:46 -0500
committerPaul Jakma <paul.jakma@hpe.com>2016-02-26 14:11:41 +0000
commit672900382d47137638086bd8351b2678f589a546 (patch)
treec6b482ed46f8dc8f0be79144173ccae152a3a726 /lib/command.c
parent40278bd4c51939ccf8ec06ef1f33aedf8f05e86c (diff)
downloadquagga-672900382d47137638086bd8351b2678f589a546.tar.bz2
quagga-672900382d47137638086bd8351b2678f589a546.tar.xz
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>
Diffstat (limited to 'lib/command.c')
-rw-r--r--lib/command.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/lib/command.c b/lib/command.c
index 37767e92..73a8a804 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -2364,7 +2364,7 @@ cmd_complete_sort(vector matchvec)
/* Command line completion support. */
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;
vector cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
@@ -2449,13 +2449,13 @@ cmd_complete_command_real (vector vline, struct vty *vty, int *status)
for (j = 0; j < vector_active (match_vector); j++)
if ((token = vector_slot (match_vector, j)))
- {
- if ((string =
- cmd_entry_function (vector_slot (vline, index),
- token)))
- if (cmd_unique_string (matchvec, string))
- vector_set (matchvec, XSTRDUP (MTYPE_TMP, string));
- }
+ {
+ string = cmd_entry_function (vector_slot (vline, index), token);
+ if (string && cmd_unique_string (matchvec, string))
+ vector_set (matchvec, (islib != 0 ?
+ XSTRDUP (MTYPE_TMP, string) :
+ strdup (string) /* rl freed */));
+ }
}
/* We don't need cmd_vector any more. */
@@ -2500,7 +2500,9 @@ cmd_complete_command_real (vector vline, struct vty *vty, int *status)
{
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);
lcdstr[lcd] = '\0';
@@ -2508,10 +2510,15 @@ cmd_complete_command_real (vector vline, struct vty *vty, int *status)
/* Free matchvec. */
for (i = 0; i < vector_active (matchvec); i++)
- {
- if (vector_slot (matchvec, i))
- XFREE (MTYPE_TMP, vector_slot (matchvec, i));
- }
+ {
+ if (vector_slot (matchvec, i))
+ {
+ if (islib != 0)
+ XFREE (MTYPE_TMP, vector_slot (matchvec, i));
+ else
+ free (vector_slot (matchvec, i));
+ }
+ }
vector_free (matchvec);
/* Make new matchvec. */
@@ -2534,7 +2541,7 @@ cmd_complete_command_real (vector vline, struct vty *vty, int *status)
}
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;
@@ -2555,15 +2562,20 @@ cmd_complete_command (vector vline, struct vty *vty, int *status)
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);
vty->node = onode;
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 */