From 25e2178ec45d1fa28dabd1561fb42d3f63e0416b Mon Sep 17 00:00:00 2001 From: c Date: Mon, 15 Apr 2024 12:10:33 -0400 Subject: There's still a use after free somewhere in there. --- src/doer.c | 84 ++++++++++++++++++++++++------------------------------ src/include/doer.h | 2 +- src/pp.c | 8 +++--- src/tree.c | 2 +- 4 files changed, 43 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/doer.c b/src/doer.c index ffcf1fc..096ab94 100644 --- a/src/doer.c +++ b/src/doer.c @@ -54,17 +54,30 @@ void doer_add_target(doer_t* doer, target_t* target) { } } -tree_t* doer_find_target_from_call(target_t* targetl, tree_t* call) { - if (!targetl) { DIE("Call to missing target."); } - - char* targname = targetl->tree->data.def.tag->data.tag.nxt->data.tag.val; - char* call_name = call->data.call.target; +tree_t* doer_find_target_from_call(doer_t* doer) { + tree_t* this_call = doer->tree; + char* call_name = this_call->data.call.target; + + target_t* target = doer->targets; + + while (target) { + tree_t* tag = target->tree->data.def.tag; + + // HACK: Not saving types, just going straight to the good stuff. + char* target_type = tag->data.tag.val; + + // Extract target's name from 2nd tag's val. + char* target_name = tag->data.tag.nxt->data.tag.val; - if (!strcmp(targname, call_name)) { - return targetl->tree; - } else { - return doer_find_target_from_call(targetl->nxt, call); + + if (!strcmp(target_name, call_name)) { + return target->tree; + } else { + target = target->nxt; + } } + + DIE("Call to missing target."); } tree_t* doer_eval_prim(doer_t* doer) { @@ -182,11 +195,11 @@ tree_t* blin_str_cat(doer_t* doer) { void doer_do_block(doer_t* doer) { if (!doer->tree) return; - tree_t* tree_root = doer->tree; + tree_t* tree_block = doer->tree; doer->tree = doer->tree->data.block.val; doer_do_expr(doer); - doer->tree = tree_root->data.block.nxt; + doer->tree = tree_block->data.block.nxt; doer_do_block(doer); } @@ -214,50 +227,27 @@ void doer_do_def(doer_t* doer) { doer_add_target(doer, target); } -#if 0 void doer_do_call(doer_t* doer) { - tree_t* oldt = doer->tree; - tree_t* blinrval = doer_do_call_blin(doer); // Could modify the *current* - // tree, but only if it's a - // blin. - - if (blinrval) { - doer->tree = blinrval; - } else { - tree_t* newt = doer_find_target_from_call(doer->targets, oldt); - doer->tree = newt->data.def.val; - } + tree_t* the_call = doer->tree; + tree_t* resolved = NULL; - tree_destroy(oldt); -} -#endif + // Could modify the *current* tree, but only if it's a blin. + resolved = doer_do_call_blin(doer); -void doer_do_call(doer_t* doer) { - tree_t* oldt = doer->tree; - tree_t* blinrval = doer_do_call_blin(doer); // Could modify the *current* - // tree, but only if it's a - // blin. - - if (blinrval) { - tree_swp_call(oldt, blinrval); - } else { - tree_t* newt = doer_find_target_from_call(doer->targets, oldt); - tree_swp_call(oldt, newt); + if (!resolved) { + doer->tree = the_call; + resolved = doer_find_target_from_call(doer); } + + tree_swp_call(the_call, resolved); + tree_destroy(the_call); + doer->tree = resolved; } tree_t* doer_do_call_blin(doer_t* doer) { - for (int i = 0; i < sizeof(blinfs) / sizeof(blinf_t); i++) { - if (!strcmp(blinfs[i].name, doer->tree->data.call.target)) { + for (int i = 0; i < sizeof(blinfs) / sizeof(blinf_t); i++) + if (!strcmp(blinfs[i].name, doer->tree->data.call.target)) return (blinfs[i].fp)(doer); - } - } return NULL; } - -// TODO: doer_do_call will check first doer_do_call_blin and then -// doer_do_call_def for user-defined functions. Will return a tree, which will -// replace the call in the tree. -// -// Maybe the parent should be set by the looping function? diff --git a/src/include/doer.h b/src/include/doer.h index a59a81a..4292ff7 100644 --- a/src/include/doer.h +++ b/src/include/doer.h @@ -47,7 +47,7 @@ typedef struct BLINF { } blinf_t; void doer_add_target(doer_t* doer, target_t* target); -tree_t* doer_find_target_from_call(target_t* targetl, tree_t* call); +tree_t* doer_find_target_from_call(doer_t* doer); // Given a tree, evaluate it to a primitive type. tree_t* doer_eval_prim(doer_t* doer); diff --git a/src/pp.c b/src/pp.c index bb77e0f..d4fc27a 100644 --- a/src/pp.c +++ b/src/pp.c @@ -19,11 +19,11 @@ void pp_destroy(pp_t* pp) { } void pp_cpy_char(pp_t* pp) { - int psize = strlen(pp->psrc); - pp->psrc = erealloc(pp->psrc, (psize + 2) * sizeof(char)); + int ppsize = strlen(pp->psrc); + pp->psrc = erealloc(pp->psrc, (ppsize + 2) * sizeof(char)); - pp->psrc[psize] = *pp->src; - pp->psrc[psize + 1] = '\0'; + pp->psrc[ppsize] = *pp->src; + pp->psrc[ppsize + 1] = '\0'; } void pp_do_reg(pp_t* pp) { diff --git a/src/tree.c b/src/tree.c index 0497f70..5a2e02d 100644 --- a/src/tree.c +++ b/src/tree.c @@ -228,7 +228,7 @@ void tree_swp_call(tree_t* t0, tree_t* t1) { break; } -// tree_destroy(t0); + tree_destroy(t0); } /* -- cgit v1.2.3