=== modified file 'ChangeLog.scripting' --- ChangeLog.scripting 2009-12-26 05:11:18 +0000 +++ ChangeLog.scripting 2009-12-27 10:26:21 +0000 @@ -1,3 +1,26 @@ +2009-12-27 BVK Chaitanya + + * include/grub/script_sh.h (grub_script_cmd_menuentry): Member + sourcecode type is reverted back to pointer to constant. + * script/script.c (grub_script_malloc): Fixed it to handle out of + memory cases gracefully. + (grub_script_add_cmd): Likewise. + (grub_script_arg_add): Likewise. + (grub_script_add_arglist): Likewise. + (grub_script_create_cmdline): Likewise. + (grub_script_create_cmdif): Likewise. + (grub_script_create_cmdmenu): Likewise, and sourcecode parameter + is used as it is. + * script/parser.y (arguments1): Added null pointer check to handle + out of memory cases. + (grubcmd): Likewise. + (commands1): Likewise. + * script/lexer.c (grub_script_lexer_record_stop): Allocates + sourcecode using grub_script_alloc, so that memory is recollected + automatically and refactored it to trim the source code. + * util/grub-script-check.c (grub_script_execute_menuentry): + Freeing sourcecode is now unnecessary, so is removed. + 2009-12-26 BVK Chaitanya * include/grub/script_sh.h: New function prototypes for === modified file 'include/grub/script_sh.h' --- include/grub/script_sh.h 2009-12-26 05:11:18 +0000 +++ include/grub/script_sh.h 2009-12-27 10:06:47 +0000 @@ -145,7 +145,7 @@ struct grub_script_arglist *arglist; /* The sourcecode the entry will be generated from. */ - char *sourcecode; + const char *sourcecode; /* Options. XXX: Not used yet. */ int options; === modified file 'script/lexer.c' --- script/lexer.c 2009-12-26 04:07:41 +0000 +++ script/lexer.c 2009-12-27 09:50:59 +0000 @@ -63,29 +63,40 @@ grub_script_lexer_record_stop (struct grub_parser_param *parser) { char *ptr; + char *result; struct grub_lexer_param *lexer = parser->lexerstate; + auto char *compact (char *start, char *end); + char *compact (char *start, char *end) + { + /* Delete '{' and '}' characters and whitespaces. */ + while (*start && grub_isspace (*start)) start++; + if (*start == '{') start++; + while (*start && grub_isspace (*start)) start++; + + while (*end && grub_isspace (*end)) end--; + if (*end == '}') end--; + while (*end && grub_isspace (*end)) end--; + *end = '\0'; + + return start; + } + if (!lexer->record || !lexer->recording) return 0; - /* Delete '{' and '}' characters. */ /* XXX This is not necessary in BASH. */ - ptr = lexer->recording + lexer->recordpos - 1; - while (*ptr && grub_isspace (*ptr)) - ptr--; - if (*ptr == '}') - *ptr = '\0'; - - ptr = lexer->recording; - while (*ptr && grub_isspace (*ptr)) - ptr++; - if (*ptr == '{') - ptr++; - + ptr = compact (lexer->recording, lexer->recording + lexer->recordpos - 1); lexer->record = 0; lexer->recordpos = 0; - return (*ptr ? grub_strdup (ptr) : 0); + + /* This memory would be freed by, grub_script_free. */ + result = grub_script_malloc (parser, grub_strlen (ptr) + 1); + if (result) + grub_strcpy (result, ptr); + + return result; } === modified file 'script/parser.y' --- script/parser.y 2009-12-26 05:11:18 +0000 +++ script/parser.y 2009-12-27 09:45:42 +0000 @@ -158,19 +158,19 @@ ; arguments1: argument arguments0 { - if ($2) + if ($1 && $2) { $1->next = $2; $1->argcount += $2->argcount; $2->argcount = 0; } $$ = $1; - } + } ; grubcmd: word arguments0 { - if ($2) { + if ($1 && $2) { $1->next = $2; $1->argcount += $2->argcount; $2->argcount = 0; @@ -197,11 +197,15 @@ struct grub_script_cmd *cmd; struct grub_script_cmdblock *cmdblock; - cmdblock = (struct grub_script_cmdblock *) $1; - cmd = cmdblock->cmdlist; - while (cmd->next) - cmd = cmd->next; - cmd->next = $3; + if ($1) + { + cmdblock = (struct grub_script_cmdblock *) $1; + cmd = cmdblock->cmdlist; + while (cmd->next) + cmd = cmd->next; + cmd->next = $3; + } + $$ = $1; } ; === modified file 'script/script.c' --- script/script.c 2009-12-26 05:11:18 +0000 +++ script/script.c 2009-12-27 10:19:35 +0000 @@ -24,12 +24,10 @@ /* It is not possible to deallocate the memory when a syntax error was found. Because of that it is required to keep track of all memory - allocations. The memory is freed in case of an error, or - assigned to the parsed script when parsing was successful. */ - -/* XXX */ - -/* In case of the normal malloc, some additional bytes are allocated + allocations. The memory is freed in case of an error, or assigned + to the parsed script when parsing was successful. + + In case of the normal malloc, some additional bytes are allocated for this datastructure. All reserved memory is stored in a linked list so it can be easily freed. The original memory can be found from &mem. */ @@ -46,6 +44,8 @@ struct grub_script_mem *mem; mem = (struct grub_script_mem *) grub_malloc (size + sizeof (*mem) - sizeof (char)); + if (!mem) + return 0; grub_dprintf ("scripting", "malloc %p\n", mem); mem->next = state->memused; @@ -115,9 +115,15 @@ argpart = (struct grub_script_arg *) grub_script_malloc (state, sizeof (*arg)); + if (!argpart) + return arg; + argpart->type = type; len = grub_strlen (str) + 1; argpart->str = grub_script_malloc (state, len); + if (!argpart->str) + return arg; /* argpart is freed later, during grub_script_free. */ + grub_memcpy (argpart->str, str, len); argpart->next = 0; @@ -144,6 +150,9 @@ link = (struct grub_script_arglist *) grub_script_malloc (state, sizeof (*link)); + if (!link) + return list; + link->next = 0; link->arg = arg; link->argcount = 0; @@ -175,6 +184,9 @@ grub_dprintf ("scripting", "cmdline\n"); cmd = grub_script_malloc (state, sizeof (*cmd)); + if (!cmd) + return 0; + cmd->cmd.exec = grub_script_execute_cmdline; cmd->cmd.next = 0; cmd->arglist = arglist; @@ -197,6 +209,9 @@ grub_dprintf ("scripting", "cmdif\n"); cmd = grub_script_malloc (state, sizeof (*cmd)); + if (!cmd) + return 0; + cmd->cmd.exec = grub_script_execute_cmdif; cmd->cmd.next = 0; cmd->exec_to_evaluate = exec_to_evaluate; @@ -262,26 +277,13 @@ char *sourcecode, int options) { struct grub_script_cmd_menuentry *cmd; - int i; - - /* Skip leading newlines to make the sourcecode better readable when - using the editor. */ - while (*sourcecode == '\n') - sourcecode++; - - /* Having trailing returns can some some annoying conflicts, remove - them. XXX: Can the parser be improved to handle this? */ - for (i = grub_strlen (sourcecode) - 1; i > 0; i--) - { - if (sourcecode[i] != '\n') - break; - sourcecode[i] = '\0'; - } cmd = grub_script_malloc (state, sizeof (*cmd)); + if (!cmd) + return 0; + cmd->cmd.exec = grub_script_execute_menuentry; cmd->cmd.next = 0; - /* XXX: Check if this memory is properly freed. */ cmd->sourcecode = sourcecode; cmd->arglist = arglist; cmd->options = options; @@ -304,9 +306,10 @@ if (!cmdblock) { - cmdblock = (struct grub_script_cmdblock *) grub_script_malloc (state, - sizeof - (*cmdblock)); + cmdblock = grub_script_malloc (state, sizeof (*cmdblock)); + if (!cmdblock) + return 0; + cmdblock->cmd.exec = grub_script_execute_cmdblock; cmdblock->cmd.next = 0; cmdblock->cmdlist = cmd; === modified file 'util/grub-script-check.c' --- util/grub-script-check.c 2009-12-26 05:11:18 +0000 +++ util/grub-script-check.c 2009-12-27 10:06:22 +0000 @@ -90,16 +90,8 @@ } grub_err_t -grub_script_execute_menuentry (struct grub_script_cmd *cmd) +grub_script_execute_menuentry (struct grub_script_cmd *cmd __attribute__ ((unused))) { - struct grub_script_cmd_menuentry *menu; - menu = (struct grub_script_cmd_menuentry *)cmd; - - if (menu->sourcecode) - { - grub_free (menu->sourcecode); - menu->sourcecode = 0; - } return 0; }