aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorc2024-03-30 11:07:53 -0400
committerc2024-03-30 11:07:53 -0400
commit68473db6798bc80aab7b39105ba88865015eb27c (patch)
tree4aec47f33e5792c1b5178d8b42da331ce3a8dd8a /src
parentc26c65dcf836a86ff3374a3e92e57ec61568e8c9 (diff)
Fixed double-free.
Was from not clearing parent tree pointers.
Diffstat (limited to 'src')
-rw-r--r--src/doer.c36
-rw-r--r--src/include/doer.h2
-rw-r--r--src/tree.c20
3 files changed, 41 insertions, 17 deletions
diff --git a/src/doer.c b/src/doer.c
index 2968882..59742ac 100644
--- a/src/doer.c
+++ b/src/doer.c
@@ -55,12 +55,12 @@ 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 value."); }
+ if (!targetl) { DIE("Call to missing target."); }
- char* last_target_name = targetl->tree->data.def.tag->data.tag.nxt->data.tag.val;
+ char* targname = targetl->tree->data.def.tag->data.tag.nxt->data.tag.val;
char* call_name = call->data.call.target;
- if (!strcmp(last_target_name, call_name)) {
+ if (!strcmp(targname, call_name)) {
return targetl->tree;
} else {
return doer_find_target_from_call(targetl->nxt, call);
@@ -74,8 +74,7 @@ char* doer_eval_str(doer_t* doer) {
switch (doer->tree->type) {
case TREE_TYPE_CALL:
- // doer->tree = doer_find_target_from_call(doer->targets, doer->tree);
- doer->tree = doer_do_call(doer);
+ doer_do_call(doer);
return doer_eval_str(doer);
case TREE_TYPE_DEF:
doer->tree = doer->tree->data.def.val;
@@ -110,6 +109,7 @@ tree_t* blin_print(doer_t* doer) {
}
tree_t* blin_printl(doer_t* doer) {
+ tree_t* oldt = doer->tree;
doer->tree = doer->tree->data.call.arg->data.carg.val;
char* strval = doer_eval_str(doer);
@@ -118,7 +118,7 @@ tree_t* blin_printl(doer_t* doer) {
strval
);
- tree_t* lstr = tree_init(TREE_TYPE_LSTR, doer->tree->parent);
+ tree_t* lstr = tree_init(TREE_TYPE_LSTR, oldt->parent);
lstr->data.lstr.val = strval;
lstr->data.lstr.len = strlen(strval);
@@ -141,9 +141,6 @@ tree_t* blin_str_cat(doer_t* doer) {
strcpy(val, str1);
strcat(val, str2);
- free(str1);
- free(str2);
-
doer->tree = tree_init(TREE_TYPE_LSTR, oldt->parent);
doer->tree->data.lstr.val = val;
@@ -187,10 +184,20 @@ void doer_do_def(doer_t* doer) {
doer_add_target(doer, target);
}
-tree_t* doer_do_call(doer_t* doer) {
- tree_t* blin = doer_do_call_blin(doer);
- if (!blin) return doer_find_target_from_call(doer->targets, doer->tree);
- else return blin;
+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_destroy(oldt);
}
tree_t* doer_do_call_blin(doer_t* doer) {
@@ -201,9 +208,6 @@ tree_t* doer_do_call_blin(doer_t* doer) {
}
}
- // Search through targets next.
- LOG_DBGF("got %s", doer->ltarget->tree->data.def.tag->data.tag.nxt->data.tag.val);
-
return NULL;
}
diff --git a/src/include/doer.h b/src/include/doer.h
index b1c8e64..0b4337b 100644
--- a/src/include/doer.h
+++ b/src/include/doer.h
@@ -68,7 +68,7 @@ static tree_type_t blin_printl_args[] = { TREE_TYPE_LSTR };
tree_t* blin_str_cat(doer_t* doer);
static tree_type_t blin_str_cat_args[] = { TREE_TYPE_LSTR, TREE_TYPE_LSTR };
-tree_t* doer_do_call(doer_t* doer);
+void doer_do_call(doer_t* doer);
tree_t* doer_do_call_blin(doer_t* doer);
tree_t* doer_do_call_def(doer_t* doer);
tree_t* doer_do_carg(doer_t* doer);
diff --git a/src/tree.c b/src/tree.c
index 84334be..6d58220 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -53,6 +53,26 @@ tree_t* tree_init(tree_type_t type, tree_t* parent) {
void tree_destroy(tree_t* tree) {
if (!tree) { return; }
+ if (tree->parent && tree->type == TREE_TYPE_CALL) {
+ tree_t* treep = tree->parent;
+ switch (treep->type) {
+ case TREE_TYPE_BLOCK:
+ treep->data.block.val = NULL;
+ break;
+ case TREE_TYPE_EXPR:
+ treep->data.expr.val = NULL;
+ break;
+ case TREE_TYPE_CARG:
+ treep->data.carg.val = NULL;
+ break;
+ case TREE_TYPE_DEF:
+ treep->data.def.val = NULL;
+ break;
+ default:
+ break;
+ }
+ }
+
switch (tree->type) {
case TREE_TYPE_BLOCK:
tree_destroy(tree->data.block.val);