poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 4/5] Fix memory leak of char* filename in pk_cmd_exec_1


From: Dan Čermák
Subject: [PATCH 4/5] Fix memory leak of char* filename in pk_cmd_exec_1
Date: Tue, 17 Dec 2019 00:45:02 +0100

From: Dan Čermák <address@hidden>

The filename is allocated but never freed.

This is fixed by introducing a macro GOTO_USAGE, that sets the return value and
besilent to 0 (i.e. unsuccessful and print usage) and jumps to the usage:
label. The code that was previously only reachable on success is now always
traversed, thereby ensuring that filename is free()'d, with the difference that
besilent is set to 1 immediately before the usage label, so that no usage is
printed in the successful case.
---
 src/pk-cmd.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/pk-cmd.c b/src/pk-cmd.c
index fbaa959..3de2851 100644
--- a/src/pk-cmd.c
+++ b/src/pk-cmd.c
@@ -247,6 +247,12 @@ pk_print_trie (int indent, struct pk_trie *trie)
 static int
 pk_cmd_exec_1 (char *str, struct pk_trie *cmds_trie, char *prefix)
 {
+#define GOTO_USAGE()                                                           
\
+  do {                                                                         
\
+    besilent = 0;                                                              
\
+    ret = 0;                                                                   
\
+    goto usage;                                                                
\
+  } while (1)
   int ret = 1;
   size_t i;
   char cmd_name[MAX_CMD_NAME], *p;
@@ -316,7 +322,7 @@ pk_cmd_exec_1 (char *str, struct pk_trie *cmds_trie, char 
*prefix)
     {
       p = skip_blanks (p);
       if (*p == '\0')
-        goto usage;
+        GOTO_USAGE();
       return pk_cmd_exec_1 (p, *cmd->subtrie, cmd_name);
     }
 
@@ -473,7 +479,7 @@ pk_cmd_exec_1 (char *str, struct pk_trie *cmds_trie, char 
*prefix)
                     *end = '\0';
 
                     if (filename[0] == '\0')
-                      goto usage;
+                      GOTO_USAGE();
 
                     switch (wordexp (filename, &exp_result, 0))
                       {
@@ -482,13 +488,13 @@ pk_cmd_exec_1 (char *str, struct pk_trie *cmds_trie, char 
*prefix)
                       case WRDE_NOSPACE:
                         wordfree (&exp_result);
                       default:
-                        goto usage;
+                        GOTO_USAGE();
                       }
 
                     if (exp_result.we_wordc != 1)
                       {
                         wordfree (&exp_result);
-                        goto usage;
+                        GOTO_USAGE();
                       }
 
                     filename = xrealloc (filename,
@@ -521,7 +527,7 @@ pk_cmd_exec_1 (char *str, struct pk_trie *cmds_trie, char 
*prefix)
 
       /* Boo, could not find valid input for this argument.  */
       if (!match)
-        goto usage;
+        GOTO_USAGE();
 
       if (*p == ',')
         p++;
@@ -539,7 +545,7 @@ pk_cmd_exec_1 (char *str, struct pk_trie *cmds_trie, char 
*prefix)
   /* Make sure there is no trailer contents in the input.  */
   p = skip_blanks (p);
   if (*p != '\0')
-    goto usage;
+    GOTO_USAGE();
 
   /* Process command flags.  */
   if (cmd->flags & PK_CMD_F_REQ_IO
@@ -563,6 +569,8 @@ pk_cmd_exec_1 (char *str, struct pk_trie *cmds_trie, char 
*prefix)
   /* Call the command handler, passing the arguments.  */
   ret = (*cmd->handler) (argc, argv, uflags);
 
+  besilent = 1;
+  usage:
   /* Free arguments occupying memory.  */
   for (i = 0; i < argc; ++i)
     {
@@ -574,12 +582,11 @@ pk_cmd_exec_1 (char *str, struct pk_trie *cmds_trie, char 
*prefix)
         pvm_destroy_routine (argv[i].val.routine);
     }
 
-  return ret;
-
- usage:
   if (!besilent)
     pk_printf (_("Usage: %s\n"), cmd->usage);
-  return 0;
+
+  return ret;
+#undef GOTO_USAGE
 }
 
 extern struct pk_cmd *info_cmds[]; /* pk-info.c  */
-- 
2.23.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]