]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
fix memory issues when used inside loops
authorBVK Chaitanya <bvk.groups@gmail.com>
Thu, 10 Jun 2010 15:19:57 +0000 (20:49 +0530)
committerBVK Chaitanya <bvk.groups@gmail.com>
Thu, 10 Jun 2010 15:19:57 +0000 (20:49 +0530)
hello/hello.c
include/grub/script_sh.h
script/argv.c
script/execute.c
script/parser.y
script/script.c

index 992c99f71162796f03c9a926748bcc7436a7185f..1189662918a0834024ad26e0b88a85073aa9941e 100644 (file)
@@ -44,16 +44,9 @@ grub_cmd_hello (grub_extcmd_context_t ctxt,
        return 1;
 
       if (script)
-       grub_script_free (script);
+       grub_script_put (script);
 
-      script = grub_malloc (sizeof (*script));
-      if (! script)
-       return 1;
-
-      script->cmd = ctxt->script_params[0]->cmd;
-      script->mem = ctxt->script_params[0]->mem;
-      ctxt->script_params[0]->cmd = 0;
-      ctxt->script_params[0]->mem = 0;
+      script = grub_script_get (ctxt->script_params[0]);
     }
 
   return 0;
@@ -71,7 +64,8 @@ GRUB_MOD_INIT(hello)
 GRUB_MOD_FINI(hello)
 {
   if (script)
-    grub_script_free (script);
+    grub_script_put (script);
 
+  script = 0;
   grub_unregister_extcmd (cmd);
 }
index a17dcca7028df5d3a03f70af7f2c6feeac105afd..2ada5d4744ec71eedca686291182258a61c39c31 100644 (file)
@@ -39,6 +39,7 @@ struct grub_script_cmd
 
 struct grub_script
 {
+  unsigned refcnt;
   struct grub_script_mem *mem;
   struct grub_script_cmd *cmd;
 };
@@ -61,7 +62,7 @@ struct grub_script_arg
   char *str;
 
   /* Parsed block argument.  */
-  struct grub_script block;
+  struct grub_script *block;
 
   /* Next argument part.  */
   struct grub_script_arg *next;
@@ -227,6 +228,8 @@ struct grub_parser_param
   struct grub_lexer_param *lexerstate;
 };
 
+void grub_script_mem_free (struct grub_script_mem *mem);
+
 void grub_script_argv_free    (struct grub_script_argv *argv);
 int grub_script_argv_next     (struct grub_script_argv *argv);
 int grub_script_argv_append   (struct grub_script_argv *argv, const char *s);
@@ -354,4 +357,20 @@ grub_err_t grub_script_function_call (grub_script_function_t func,
 char **
 grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count);
 
+static inline struct grub_script *
+grub_script_get (struct grub_script *script)
+{
+  script->refcnt++;
+  return script;
+}
+
+static inline void
+grub_script_put (struct grub_script *script)
+{
+  if (script->refcnt == 0)
+    grub_script_free (script);
+  else
+    script->refcnt--;
+}
+
 #endif /* ! GRUB_NORMAL_PARSER_HEADER */
index f962556d8ad10603aaf34b654521ffe518438c8d..8dd56334582048b209bfbd6c305dbb46687b40f8 100644 (file)
@@ -55,7 +55,8 @@ grub_script_argv_free (struct grub_script_argv *argv)
   if (argv->scripts)
     {
       for (i = 0; i < argv->argc; i++)
-       grub_script_free (argv->scripts[i]);
+       if (argv->scripts[i])
+         grub_script_put (argv->scripts[i]);
 
       grub_free (argv->scripts);
     }
@@ -127,17 +128,10 @@ int
 grub_script_argv_script_append (struct grub_script_argv *argv,
                                struct grub_script *script)
 {
-  struct grub_script *s;
-
-  s = grub_malloc (sizeof (*s));
-  if (! s)
-    return 1;
-
   if (argv->scripts[argv->argc - 1])
-    grub_script_free (argv->scripts[argv->argc - 1]);
+    grub_script_put (argv->scripts[argv->argc - 1]);
 
-  *s = *script;
-  argv->scripts[argv->argc - 1] = s;
+  argv->scripts[argv->argc - 1] = grub_script_get (script);
   return 0;
 }
 
index 0ac42cf4ac6261a788ba803a51850d5285a02b8e..c6a6c2484c2981ab6e18f8c4c97ac0aede3f3f17 100644 (file)
@@ -198,7 +198,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist,
 
            case GRUB_SCRIPT_ARG_TYPE_BLOCK:
              if (grub_script_argv_append (&result, arg->str) ||
-                 grub_script_argv_script_append (&result, &arg->block))
+                 grub_script_argv_script_append (&result, arg->block))
                goto fail;
              break;
 
index d774ca9189469a6fce22a0e38338edfec6da0d96..1202fef2972b3bb54bba3bf8c6fc4c26a197ae66 100644 (file)
@@ -164,11 +164,9 @@ block: "{"
          if ((p = grub_script_lexer_record_stop (state, $<offset>2)))
           *grub_strrchr (p, '}') = '\0';
 
-         if ((arg = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_BLOCK, p)))
-          {
-            arg->block.cmd = $3;
-            arg->block.mem = memory;
-          }
+        arg = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_BLOCK, p);
+        if (! arg || ! (arg->block = grub_script_create ($3, memory)))
+          grub_script_mem_free (memory);
 
          $$ = grub_script_add_arglist (state, 0, arg);
          grub_script_lexer_deref (state->lexerstate);
@@ -256,8 +254,10 @@ function: "function" "name"
             state->func_mem = grub_script_mem_record_stop (state,
                                                            state->func_mem);
             script = grub_script_create ($6, state->func_mem);
-            if (script)
-              grub_script_function_create ($2, script);
+            if (! script)
+             grub_script_mem_free (state->func_mem);
+           else
+             grub_script_function_create ($2, script);
 
             grub_script_lexer_deref (state->lexerstate);
           }
index 9017a08e8dd0ae552d04529bba78e80c3292c489..b7cbdff1daa4646570078f3ac728a22c49b6119c 100644 (file)
@@ -54,7 +54,7 @@ grub_script_malloc (struct grub_parser_param *state, grub_size_t size)
 }
 
 /* Free all memory described by MEM.  */
-static void
+void
 grub_script_mem_free (struct grub_script_mem *mem)
 {
   struct grub_script_mem *memfree;
@@ -122,8 +122,7 @@ grub_script_arg_add (struct grub_parser_param *state,
     return arg;
 
   argpart->type = type;
-  argpart->block.mem = 0;
-  argpart->block.cmd = 0;
+  argpart->block = 0;
 
   len = grub_strlen (str) + 1;
   argpart->str = grub_script_malloc (state, len);
@@ -341,16 +340,12 @@ grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem)
   struct grub_script *parsed;
 
   parsed = grub_malloc (sizeof (*parsed));
-  if (!parsed)
-    {
-      grub_script_mem_free (mem);
-      grub_free (cmd);
-
-      return 0;
-    }
+  if (! parsed)
+    return 0;
 
   parsed->mem = mem;
   parsed->cmd = cmd;
+  parsed->refcnt = 0;
 
   return parsed;
 }
@@ -365,7 +360,7 @@ grub_script_parse (char *script, grub_reader_getline_t getline)
   struct grub_lexer_param *lexstate;
   struct grub_parser_param *parsestate;
 
-  parsed = grub_malloc (sizeof (*parsed));
+  parsed = grub_script_create (0, 0);
   if (!parsed)
     return 0;