From ce80fffe698e2743816dfe04c25f23c901e1968f Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Wed, 26 Feb 2003 07:44:34 +0000 Subject: [PATCH] Massive bug and memory leak fixing. --- libs/gib/gib_execute.c | 18 ++++++++++-------- libs/gib/gib_parse.c | 37 ++++++++++++++++++++++++++----------- libs/gib/gib_process.c | 2 +- libs/util/cbuf.c | 3 ++- tools/carne/main.c | 15 +++++++++------ 5 files changed, 48 insertions(+), 27 deletions(-) diff --git a/libs/gib/gib_execute.c b/libs/gib/gib_execute.c index 8707ef77a..1a179f5b8 100644 --- a/libs/gib/gib_execute.c +++ b/libs/gib/gib_execute.c @@ -200,8 +200,16 @@ GIB_Execute (cbuf_t * cbuf) unsigned int index; gib_var_t *var; + if (!g->program) + return; g->ip = g->ip ? g->ip->next : g->program; while (g->ip) { + if (g->ip->flags & TREE_L_EMBED) { + // Get ready for return values + g->waitret = true; + GIB_Buffer_Push_Sstack (cbuf); + } else + g->waitret = false; switch (g->ip->type) { case TREE_T_JUMP: g->ip = g->ip->jump; @@ -231,12 +239,6 @@ GIB_Execute (cbuf_t * cbuf) g->ip = g->ip->next; continue; case TREE_T_CMD: - if (g->ip->flags & TREE_L_EMBED) { - // Get ready for return values - g->waitret = true; - GIB_Buffer_Push_Sstack (cbuf); - } else - g->waitret = false; if (GIB_Execute_Prepare_Line (cbuf, g->ip)) return; else if (cbuf->args->argc) { @@ -264,6 +266,6 @@ GIB_Execute (cbuf_t * cbuf) return; } } - g->ip = g->program = 0; - g->script = 0; + g->ip = 0; + GIB_Tree_Unref (&g->program); } diff --git a/libs/gib/gib_parse.c b/libs/gib/gib_parse.c index 18b11634c..3d4cc3234 100644 --- a/libs/gib/gib_parse.c +++ b/libs/gib/gib_parse.c @@ -299,6 +299,7 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs, gib_t cur->end = *i + pofs; cur->delim = delim; str = calloc (*i - tstart + 1, sizeof (char)); + cur->str = str; memcpy (str, program + tstart, *i - tstart); if (cur->delim == '{') { if (cat == CAT_CONCAT) { @@ -344,7 +345,6 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs, gib_t // We can handle escape characters now } else if (cur->delim == '\"') GIB_Process_Escapes (str); - cur->str = str; if (cat == CAT_CONCAT) cur->flags |= TREE_A_CONCAT; @@ -363,7 +363,9 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs, gib_t if (c) GIB_Parse_Error (va ("Could not find match for '%c'.", c), *i + pofs); if (nodes) - GIB_Tree_Free_Recursive (nodes); + GIB_Tree_Unref (&nodes); + if (embs) + GIB_Tree_Unref (&embs); return 0; } @@ -372,6 +374,9 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t * line) { gib_tree_t *p, *start = line; + // If second token is concatenated, than the first can't possibly mean anything + if (line->children->next && line->children->next->flags & TREE_A_CONCAT) + return line; while (!strcmp (line->children->str, "if") || !strcmp (line->children->str, "ifnot")) { // Sanity checking @@ -542,8 +547,13 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t * line) p->jump = line; p = p->next; } - } else if (line->children->next && line->children->next->delim == ' ' && !strcmp (line->children->next->str, "=")) - line->type = TREE_T_ASSIGN; + } else if ( + line->children->next && + !(line->children->next->flags & TREE_A_CONCAT) && + line->children->next->delim == ' ' && + !strcmp (line->children->next->str, "=") + ) + line->type = TREE_T_ASSIGN; return line; } @@ -588,7 +598,7 @@ GIB_Parse_Lines (const char *program, unsigned int pofs) return lines; ERROR: if (lines) - GIB_Tree_Free_Recursive (lines); + GIB_Tree_Unref (&lines); return 0; } @@ -597,10 +607,11 @@ GIB_Parse_Embedded (const char *program, unsigned int pofs, gib_tree_t ** embedd { unsigned int i, n, t; char c, d, *str; - gib_tree_t *lines = 0, **line = &lines, *cur, *tokens, *emb, *tmp; + gib_tree_t *lines = 0, **line = &lines, *cur, *tokens, *emb, *tmp, **embfirst; unsigned int start, end; gib_parse_error = false; + embfirst = embedded; *embedded = 0; for (i = 0; program[i]; i++) { @@ -628,14 +639,16 @@ GIB_Parse_Embedded (const char *program, unsigned int pofs, gib_tree_t ** embedd cur->end = end + pofs; c = 0; t = 0; - if (! - (tokens = - GIB_Parse_Tokens (cur->str, &t, start + pofs, &emb))) + if (!(tokens = GIB_Parse_Tokens (cur->str, &t, start + pofs, &emb))) { + GIB_Tree_Unref (&cur); goto ERROR; + } cur->children = tokens; GIB_Parse_Semantic_Preprocess (cur)->next = *embedded; - if (gib_parse_error) + if (gib_parse_error) { + GIB_Tree_Unref (&cur); goto ERROR; + } // Did this have embedded commands of it's own? if (emb) { // Link them in first @@ -692,6 +705,8 @@ GIB_Parse_Embedded (const char *program, unsigned int pofs, gib_tree_t ** embedd if (c) GIB_Parse_Error (va ("Could not find match for '%c'.", c), i + pofs); if (lines) - GIB_Tree_Free_Recursive (lines); + GIB_Tree_Unref (&lines); + if (*embfirst) + GIB_Tree_Unref (embfirst); return 0; } diff --git a/libs/gib/gib_process.c b/libs/gib/gib_process.c index af714c9b8..3a9c8031a 100644 --- a/libs/gib/gib_process.c +++ b/libs/gib/gib_process.c @@ -95,7 +95,7 @@ GIB_Process_Embedded (gib_tree_t * node, cbuf_args_t * args) Cbuf_ArgsAdd (args, retvals->dstrs[j]->str); args->argm[args->argc - 1] = node; } - if (str[prev] && retvals->size) // Still more stuff left? + if (str[prev] || retvals->size) // Still more stuff left? Cbuf_ArgsAdd (args, ""); } else dstring_appendstr (args->argv[args->argc - 1], diff --git a/libs/util/cbuf.c b/libs/util/cbuf.c index 977dc1b75..917c28fda 100644 --- a/libs/util/cbuf.c +++ b/libs/util/cbuf.c @@ -68,6 +68,7 @@ Cbuf_ArgsDelete (cbuf_args_t *args) dstring_delete (args->argv[i]); free (args->argv); free (args->args); + free (args->argm); free (args); } @@ -201,7 +202,7 @@ Cbuf_Execute_Stack (cbuf_t *cbuf) Cbuf_DeleteStack (cbuf->down); cbuf->down = 0; } - if (sp) // This should be null if we exited normally + if (sp) Cbuf_Reset (cbuf); } diff --git a/tools/carne/main.c b/tools/carne/main.c index ab0a7225a..ca5c09e63 100644 --- a/tools/carne/main.c +++ b/tools/carne/main.c @@ -64,13 +64,14 @@ Carne_Execute_Script (const char *path, cbuf_args_t *args) Qclose (file); } else { printf ("Could not open %s for reading: %s\n", path, strerror(errno)); - return 1; + carne_exitcode = 1; + goto ERROR; } - if (gib_parse_error) - return 1; - - + if (gib_parse_error) { + carne_exitcode = 2; + goto ERROR; + } GIB_Function_Prepare_Args (mbuf, args->argv, args->argc); @@ -82,6 +83,7 @@ Carne_Execute_Script (const char *path, cbuf_args_t *args) if (carne_done || !GIB_DATA(mbuf)->program) break; } +ERROR: Cbuf_DeleteStack (mbuf); return carne_exitcode; } @@ -109,7 +111,7 @@ Carne_Execute_Stdin (void) int main (int argc, char **argv) { - cbuf_args_t *args = Cbuf_ArgsNew (); + cbuf_args_t *args; int result, i; // Initialize required QF subsystems @@ -122,6 +124,7 @@ main (int argc, char **argv) if (argc > 1) { // Prepare arguments + args = Cbuf_ArgsNew (); for (i = 1; i < argc; i++) Cbuf_ArgsAdd (args, argv[i]); // Run the script