From: Lou Berger Date: Tue, 12 Jan 2016 18:41:46 +0000 (-0500) Subject: lib: fix bookkeeping for libreadline malloc()s X-Git-Tag: frr-2.0-rc1~608 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=cde9f1011728e6b4f141fa7d5d4656cfa6d46293;p=matthieu%2Ffrr.git 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 Signed-off-by: David Lamparter (cherry picked from commit 672900382d47137638086bd8351b2678f589a546) Conflicts: lib/command.c --- diff --git a/lib/command.c b/lib/command.c index d080d6cc0b..dd98eb2de5 100644 --- a/lib/command.c +++ b/lib/command.c @@ -2349,7 +2349,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)); @@ -2434,13 +2434,14 @@ 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->cmd))) - if (cmd_unique_string (matchvec, string)) - vector_set (matchvec, XSTRDUP (MTYPE_TMP, string)); - } + { + string = cmd_entry_function (vector_slot (vline, index), + token->cmd); + 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. */ @@ -2485,7 +2486,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'; @@ -2493,10 +2496,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. */ @@ -2519,7 +2527,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; @@ -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)); } - 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 */ diff --git a/lib/command.h b/lib/command.h index 7051e1ca5c..4be9514e85 100644 --- a/lib/command.h +++ b/lib/command.h @@ -550,6 +550,7 @@ extern vector cmd_make_strvec (const char *); extern void cmd_free_strvec (vector); 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_lib (vector, struct vty *, int *status, int islib); 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 config_from_file (struct vty *, FILE *, unsigned int *line_num); diff --git a/lib/vty.c b/lib/vty.c index 0de075ccbf..53c9a2aba0 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -873,7 +873,7 @@ vty_complete_command (struct vty *vty) if (isspace ((int) vty->buf[vty->length - 1])) vector_set (vline, NULL); - matched = cmd_complete_command (vline, vty, &ret); + matched = cmd_complete_command_lib (vline, vty, &ret, 1); cmd_free_strvec (vline);