From 12e93e7c7721f9a581f62a8df9534571d0ec353d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 23 Mar 2020 12:59:56 -0400 Subject: opt: Avoid dangling pointers in de_morgan() If optimize_{and,or}_expr() relocates expr, we need to update the parent expr or else we might return garbage. It seems impossible to actually trigger this bug right now, since the {and,or} optimizations are symmetric, but it could be hit if the simplifications in de_morgan() expose more information than was known previously. --- opt.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'opt.c') diff --git a/opt.c b/opt.c index 019a136..57f5dbf 100644 --- a/opt.c +++ b/opt.c @@ -308,11 +308,11 @@ static struct expr *de_morgan(const struct opt_state *state, struct expr *expr, has_parent = false; } + assert(expr->eval == eval_and || expr->eval == eval_or); if (expr->eval == eval_and) { expr->eval = eval_or; expr->argv = &fake_or_arg; } else { - assert(expr->eval == eval_or); expr->eval = eval_and; expr->argv = &fake_and_arg; } @@ -342,11 +342,13 @@ static struct expr *de_morgan(const struct opt_state *state, struct expr *expr, } else { expr = optimize_or_expr(state, expr); } + if (has_parent) { + parent->rhs = expr; + } else { + parent = expr; + } if (!expr) { - if (has_parent) { - parent->rhs = NULL; - free_expr(parent); - } + free_expr(parent); return NULL; } -- cgit v1.2.3