]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: fix bookkeeping for libreadline malloc()s
authorLou Berger <lberger@labn.net>
Tue, 12 Jan 2016 18:41:46 +0000 (13:41 -0500)
committervivek <vivek@cumulusnetworks.com>
Mon, 6 Jun 2016 21:34:42 +0000 (14:34 -0700)
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

lib/command.c
lib/command.h
lib/vty.c

index d080d6cc0b2aa458ff5327254c251835db2ed199..dd98eb2de5995fcc2c1fa4d359bb88312bf69b80 100644 (file)
@@ -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 */
index 7051e1ca5c34d2c51dabfbc989746cd5b9b17463..4be9514e85e88045689c434c249a066964db1f3c 100644 (file)
@@ -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);
index 0de075ccbf8901d4367a834f2d355ccc597b024a..53c9a2aba0772ebba6f23bd0af2d7c86095988de 100644 (file)
--- 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);