summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2020-09-08 20:12:39 +0200
committerJo-Philipp Wich <jo@mein.io>2020-09-08 20:12:39 +0200
commitc735882bb492ff81f98773186652dbe878ff3d60 (patch)
tree4cbfadecef27402605a00298222c223f8ccccb51
parent42e8fcddf0ec78d81d6733c8a14592df9dcb2381 (diff)
parser, eval: use an ut_op flag to denote postfix access
The current code still abused the JSON value pointer to denote postfix access for certain operations which led to a crash when freeing the parser state due to an attempt to put a (void *)1 pointer. Since we do have the ability to set flags on operations since the AST rework, use this much cleaner approach and avoid the invalid pointer hackery. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--ast.h1
-rw-r--r--eval.c4
-rw-r--r--parser.y6
3 files changed, 6 insertions, 5 deletions
diff --git a/ast.h b/ast.h
index b45ee41..9bb6696 100644
--- a/ast.h
+++ b/ast.h
@@ -55,6 +55,7 @@ struct ut_op {
uint16_t is_first:1;
uint16_t is_op:1;
uint16_t is_overflow:1;
+ uint16_t is_postfix:1;
uint32_t off;
struct json_object *val;
union {
diff --git a/eval.c b/eval.c
index 4bcc2b2..d2099dd 100644
--- a/eval.c
+++ b/eval.c
@@ -804,7 +804,7 @@ ut_execute_inc_dec(struct ut_state *state, uint32_t off)
ut_putval(ut_setval(scope, key, nval));
/* postfix inc/dec, return old val */
- if (op->val)
+ if (op->is_postfix)
return val;
ut_putval(val);
@@ -1292,7 +1292,7 @@ ut_execute_op(struct ut_state *state, uint32_t off)
case T_LBRACK:
/* postfix access */
- if (op->val) {
+ if (op->is_postfix) {
scope = ut_getref_required(state, off, &key);
state->ctx = scope;
diff --git a/parser.y b/parser.y
index ff475f1..33ff24e 100644
--- a/parser.y
+++ b/parser.y
@@ -254,14 +254,14 @@ unary_exp(A) ::= T_COMPL(B) unary_exp(C). { A = wrap_op(B, C); }
unary_exp(A) ::= T_NOT(B) unary_exp(C). { A = wrap_op(B, C); }
unary_exp(A) ::= postfix_exp(B). { A = B; }
-postfix_exp(A) ::= unary_exp(B) T_INC(C). { A = wrap_op(C, B); ut_get_op(s, A)->val = (void *)1; }
-postfix_exp(A) ::= unary_exp(B) T_DEC(C). { A = wrap_op(C, B); ut_get_op(s, A)->val = (void *)1; }
+postfix_exp(A) ::= unary_exp(B) T_INC(C). { A = wrap_op(C, B); ut_get_op(s, A)->is_postfix = 1; }
+postfix_exp(A) ::= unary_exp(B) T_DEC(C). { A = wrap_op(C, B); ut_get_op(s, A)->is_postfix = 1; }
postfix_exp(A) ::= unary_exp(B) T_LPAREN(C) T_RPAREN. { A = wrap_op(C, B); }
postfix_exp(A) ::= unary_exp(B) T_LPAREN(C) arg_exp(D) T_RPAREN.
{ A = wrap_op(C, B, D); }
postfix_exp(A) ::= postfix_exp(B) T_DOT(C) T_LABEL(D). { A = wrap_op(C, B, D); }
postfix_exp(A) ::= postfix_exp(B) T_LBRACK(C) assign_exp(D) T_RBRACK.
- { A = wrap_op(C, B, D); ut_get_op(s, A)->val = (void *)1; }
+ { A = wrap_op(C, B, D); ut_get_op(s, A)->is_postfix = 1; }
postfix_exp(A) ::= primary_exp(B). { A = B; }
primary_exp(A) ::= T_BOOL(B). { A = B; }