Skip to content

Commit

Permalink
Fix crash in query DSL parser when using Rel(X, Y, Z) syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Dec 12, 2023
1 parent 792b91e commit f15c797
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 1 deletion.
2 changes: 2 additions & 0 deletions flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -11305,6 +11305,8 @@ ecs_filter_t* ecs_filter_init(
if (ptr[0] == '\n') {
break;
}

ecs_os_zeromem(extra_args);
}

if (!ptr) {
Expand Down
2 changes: 2 additions & 0 deletions src/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1530,6 +1530,8 @@ ecs_filter_t* ecs_filter_init(
if (ptr[0] == '\n') {
break;
}

ecs_os_zeromem(extra_args);
}

if (!ptr) {
Expand Down
3 changes: 3 additions & 0 deletions test/addons/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@
"pair_4_args",
"pair_4_args_implicit_this",
"pair_3_args_2_terms",
"pair_3_args_this_tgt",
"pair_3_args_2_terms_this_tgt",
"pair_3_args_2_terms_this_tgt_implicit_this",
"cascade_desc"
]
}, {
Expand Down
104 changes: 104 additions & 0 deletions test/addons/src/Parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -5555,3 +5555,107 @@ void Parser_cascade_desc(void) {

ecs_fini(world);
}

void Parser_pair_3_args_this_tgt(void) {
ecs_world_t *world = ecs_mini();

ECS_TAG(world, Rel);
ECS_TAG(world, Tgt);

ecs_filter_t f = ECS_FILTER_INIT;
test_assert(NULL != ecs_filter_init(world, &(ecs_filter_desc_t){
.storage = &f,
.expr = "ChildOf($grandchild, $child, $this)"
}));

test_int(filter_count(&f), 2);

ecs_term_t *terms = filter_terms(&f);
test_first(terms[0], EcsChildOf, EcsSelf|EcsIsEntity);
test_src_var(terms[0], 0, EcsSelf|EcsIsVariable, "grandchild");
test_second_var(terms[0], 0, EcsSelf|EcsIsVariable, "child");
test_int(terms[0].oper, EcsAnd);
test_int(terms[0].inout, EcsInOutDefault);

test_first(terms[1], EcsChildOf, EcsSelf|EcsIsEntity);
test_src_var(terms[1], 0, EcsSelf|EcsIsVariable, "child");
test_second(terms[1], EcsThis, EcsSelf|EcsIsVariable);
test_int(terms[1].oper, EcsAnd);
test_int(terms[1].inout, EcsInOutDefault);

ecs_filter_fini(&f);

ecs_fini(world);
}

void Parser_pair_3_args_2_terms_this_tgt(void) {
ecs_world_t *world = ecs_mini();

ECS_TAG(world, Rel);

ecs_filter_t f = ECS_FILTER_INIT;
test_assert(NULL != ecs_filter_init(world, &(ecs_filter_desc_t){
.storage = &f,
.expr = "ChildOf($grandchild, $child, $this), Rel($this)"
}));

test_int(filter_count(&f), 3);

ecs_term_t *terms = filter_terms(&f);
test_first(terms[0], EcsChildOf, EcsSelf|EcsIsEntity);
test_src_var(terms[0], 0, EcsSelf|EcsIsVariable, "grandchild");
test_second_var(terms[0], 0, EcsSelf|EcsIsVariable, "child");
test_int(terms[0].oper, EcsAnd);
test_int(terms[0].inout, EcsInOutDefault);

test_first(terms[1], EcsChildOf, EcsSelf|EcsIsEntity);
test_src_var(terms[1], 0, EcsSelf|EcsIsVariable, "child");
test_second(terms[1], EcsThis, EcsSelf|EcsIsVariable);
test_int(terms[1].oper, EcsAnd);
test_int(terms[1].inout, EcsInOutDefault);

test_first(terms[2], Rel, EcsSelf|EcsIsEntity);
test_src(terms[2], EcsThis, EcsSelf|EcsUp|EcsIsVariable);
test_int(terms[2].oper, EcsAnd);
test_int(terms[2].inout, EcsInOutDefault);

ecs_filter_fini(&f);

ecs_fini(world);
}

void Parser_pair_3_args_2_terms_this_tgt_implicit_this(void) {
ecs_world_t *world = ecs_mini();

ECS_TAG(world, Rel);

ecs_filter_t f = ECS_FILTER_INIT;
test_assert(NULL != ecs_filter_init(world, &(ecs_filter_desc_t){
.storage = &f,
.expr = "ChildOf($grandchild, $child, $this), Rel"
}));

test_int(filter_count(&f), 3);

ecs_term_t *terms = filter_terms(&f);
test_first(terms[0], EcsChildOf, EcsSelf|EcsIsEntity);
test_src_var(terms[0], 0, EcsSelf|EcsIsVariable, "grandchild");
test_second_var(terms[0], 0, EcsSelf|EcsIsVariable, "child");
test_int(terms[0].oper, EcsAnd);
test_int(terms[0].inout, EcsInOutDefault);

test_first(terms[1], EcsChildOf, EcsSelf|EcsIsEntity);
test_src_var(terms[1], 0, EcsSelf|EcsIsVariable, "child");
test_second(terms[1], EcsThis, EcsSelf|EcsIsVariable);
test_int(terms[1].oper, EcsAnd);
test_int(terms[1].inout, EcsInOutDefault);

test_first(terms[2], Rel, EcsSelf|EcsIsEntity);
test_src(terms[2], EcsThis, EcsSelf|EcsUp|EcsIsVariable);
test_int(terms[2].oper, EcsAnd);
test_int(terms[2].inout, EcsInOutDefault);

ecs_filter_fini(&f);

ecs_fini(world);
}
17 changes: 16 additions & 1 deletion test/addons/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ void Parser_pair_3_args_implicit_this(void);
void Parser_pair_4_args(void);
void Parser_pair_4_args_implicit_this(void);
void Parser_pair_3_args_2_terms(void);
void Parser_pair_3_args_this_tgt(void);
void Parser_pair_3_args_2_terms_this_tgt(void);
void Parser_pair_3_args_2_terms_this_tgt_implicit_this(void);
void Parser_cascade_desc(void);

// Testsuite 'Plecs'
Expand Down Expand Up @@ -2674,6 +2677,18 @@ bake_test_case Parser_testcases[] = {
"pair_3_args_2_terms",
Parser_pair_3_args_2_terms
},
{
"pair_3_args_this_tgt",
Parser_pair_3_args_this_tgt
},
{
"pair_3_args_2_terms_this_tgt",
Parser_pair_3_args_2_terms_this_tgt
},
{
"pair_3_args_2_terms_this_tgt_implicit_this",
Parser_pair_3_args_2_terms_this_tgt_implicit_this
},
{
"cascade_desc",
Parser_cascade_desc
Expand Down Expand Up @@ -8506,7 +8521,7 @@ static bake_test_suite suites[] = {
"Parser",
NULL,
NULL,
232,
235,
Parser_testcases
},
{
Expand Down

0 comments on commit f15c797

Please sign in to comment.