added maximum recursion depth

This commit is contained in:
Daniel Holden
2019-09-01 13:32:36 -04:00
parent 9716397357
commit ea778d1b8d

37
mpc.c
View File

@@ -1038,13 +1038,20 @@ enum {
if (x) { MPC_SUCCESS(r->output); } \ if (x) { MPC_SUCCESS(r->output); } \
else { MPC_FAILURE(NULL); } else { MPC_FAILURE(NULL); }
static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_err_t **e) { #define MPC_MAX_RECURSION_DEPTH 1000
static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_err_t **e, int depth) {
int j = 0, k = 0; int j = 0, k = 0;
mpc_result_t results_stk[MPC_PARSE_STACK_MIN]; mpc_result_t results_stk[MPC_PARSE_STACK_MIN];
mpc_result_t *results; mpc_result_t *results;
int results_slots = MPC_PARSE_STACK_MIN; int results_slots = MPC_PARSE_STACK_MIN;
if (depth == MPC_MAX_RECURSION_DEPTH)
{
MPC_FAILURE(mpc_err_fail(i, "Maximum recursion depth exceeded!"));
}
switch (p->type) { switch (p->type) {
/* Basic Parsers */ /* Basic Parsers */
@@ -1072,21 +1079,21 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
/* Application Parsers */ /* Application Parsers */
case MPC_TYPE_APPLY: case MPC_TYPE_APPLY:
if (mpc_parse_run(i, p->data.apply.x, r, e)) { if (mpc_parse_run(i, p->data.apply.x, r, e, depth+1)) {
MPC_SUCCESS(mpc_parse_apply(i, p->data.apply.f, r->output)); MPC_SUCCESS(mpc_parse_apply(i, p->data.apply.f, r->output));
} else { } else {
MPC_FAILURE(r->output); MPC_FAILURE(r->output);
} }
case MPC_TYPE_APPLY_TO: case MPC_TYPE_APPLY_TO:
if (mpc_parse_run(i, p->data.apply_to.x, r, e)) { if (mpc_parse_run(i, p->data.apply_to.x, r, e, depth+1)) {
MPC_SUCCESS(mpc_parse_apply_to(i, p->data.apply_to.f, r->output, p->data.apply_to.d)); MPC_SUCCESS(mpc_parse_apply_to(i, p->data.apply_to.f, r->output, p->data.apply_to.d));
} else { } else {
MPC_FAILURE(r->error); MPC_FAILURE(r->error);
} }
case MPC_TYPE_CHECK: case MPC_TYPE_CHECK:
if (mpc_parse_run(i, p->data.check.x, r, e)) { if (mpc_parse_run(i, p->data.check.x, r, e, depth+1)) {
if (p->data.check.f(&r->output)) { if (p->data.check.f(&r->output)) {
MPC_SUCCESS(r->output); MPC_SUCCESS(r->output);
} else { } else {
@@ -1098,7 +1105,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
} }
case MPC_TYPE_CHECK_WITH: case MPC_TYPE_CHECK_WITH:
if (mpc_parse_run(i, p->data.check_with.x, r, e)) { if (mpc_parse_run(i, p->data.check_with.x, r, e, depth+1)) {
if (p->data.check_with.f(&r->output, p->data.check_with.d)) { if (p->data.check_with.f(&r->output, p->data.check_with.d)) {
MPC_SUCCESS(r->output); MPC_SUCCESS(r->output);
} else { } else {
@@ -1111,7 +1118,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
case MPC_TYPE_EXPECT: case MPC_TYPE_EXPECT:
mpc_input_suppress_enable(i); mpc_input_suppress_enable(i);
if (mpc_parse_run(i, p->data.expect.x, r, e)) { if (mpc_parse_run(i, p->data.expect.x, r, e, depth+1)) {
mpc_input_suppress_disable(i); mpc_input_suppress_disable(i);
MPC_SUCCESS(r->output); MPC_SUCCESS(r->output);
} else { } else {
@@ -1121,7 +1128,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
case MPC_TYPE_PREDICT: case MPC_TYPE_PREDICT:
mpc_input_backtrack_disable(i); mpc_input_backtrack_disable(i);
if (mpc_parse_run(i, p->data.predict.x, r, e)) { if (mpc_parse_run(i, p->data.predict.x, r, e, depth+1)) {
mpc_input_backtrack_enable(i); mpc_input_backtrack_enable(i);
MPC_SUCCESS(r->output); MPC_SUCCESS(r->output);
} else { } else {
@@ -1136,7 +1143,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
case MPC_TYPE_NOT: case MPC_TYPE_NOT:
mpc_input_mark(i); mpc_input_mark(i);
mpc_input_suppress_enable(i); mpc_input_suppress_enable(i);
if (mpc_parse_run(i, p->data.not.x, r, e)) { if (mpc_parse_run(i, p->data.not.x, r, e, depth+1)) {
mpc_input_rewind(i); mpc_input_rewind(i);
mpc_input_suppress_disable(i); mpc_input_suppress_disable(i);
mpc_parse_dtor(i, p->data.not.dx, r->output); mpc_parse_dtor(i, p->data.not.dx, r->output);
@@ -1148,7 +1155,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
} }
case MPC_TYPE_MAYBE: case MPC_TYPE_MAYBE:
if (mpc_parse_run(i, p->data.not.x, r, e)) { if (mpc_parse_run(i, p->data.not.x, r, e, depth+1)) {
MPC_SUCCESS(r->output); MPC_SUCCESS(r->output);
} else { } else {
*e = mpc_err_merge(i, *e, r->error); *e = mpc_err_merge(i, *e, r->error);
@@ -1161,7 +1168,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
results = results_stk; results = results_stk;
while (mpc_parse_run(i, p->data.repeat.x, &results[j], e)) { while (mpc_parse_run(i, p->data.repeat.x, &results[j], e, depth+1)) {
j++; j++;
if (j == MPC_PARSE_STACK_MIN) { if (j == MPC_PARSE_STACK_MIN) {
results_slots = j + j / 2; results_slots = j + j / 2;
@@ -1183,7 +1190,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
results = results_stk; results = results_stk;
while (mpc_parse_run(i, p->data.repeat.x, &results[j], e)) { while (mpc_parse_run(i, p->data.repeat.x, &results[j], e, depth+1)) {
j++; j++;
if (j == MPC_PARSE_STACK_MIN) { if (j == MPC_PARSE_STACK_MIN) {
results_slots = j + j / 2; results_slots = j + j / 2;
@@ -1214,7 +1221,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
? mpc_malloc(i, sizeof(mpc_result_t) * p->data.repeat.n) ? mpc_malloc(i, sizeof(mpc_result_t) * p->data.repeat.n)
: results_stk; : results_stk;
while (mpc_parse_run(i, p->data.repeat.x, &results[j], e)) { while (mpc_parse_run(i, p->data.repeat.x, &results[j], e, depth+1)) {
j++; j++;
if (j == p->data.repeat.n) { break; } if (j == p->data.repeat.n) { break; }
} }
@@ -1243,7 +1250,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
: results_stk; : results_stk;
for (j = 0; j < p->data.or.n; j++) { for (j = 0; j < p->data.or.n; j++) {
if (mpc_parse_run(i, p->data.or.xs[j], &results[j], e)) { if (mpc_parse_run(i, p->data.or.xs[j], &results[j], e, depth+1)) {
MPC_SUCCESS(results[j].output; MPC_SUCCESS(results[j].output;
if (p->data.or.n > MPC_PARSE_STACK_MIN) { mpc_free(i, results); }); if (p->data.or.n > MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
} else { } else {
@@ -1264,7 +1271,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
mpc_input_mark(i); mpc_input_mark(i);
for (j = 0; j < p->data.and.n; j++) { for (j = 0; j < p->data.and.n; j++) {
if (!mpc_parse_run(i, p->data.and.xs[j], &results[j], e)) { if (!mpc_parse_run(i, p->data.and.xs[j], &results[j], e, depth+1)) {
mpc_input_rewind(i); mpc_input_rewind(i);
for (k = 0; k < j; k++) { for (k = 0; k < j; k++) {
mpc_parse_dtor(i, p->data.and.dxs[k], results[k].output); mpc_parse_dtor(i, p->data.and.dxs[k], results[k].output);
@@ -1297,7 +1304,7 @@ int mpc_parse_input(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r) {
int x; int x;
mpc_err_t *e = mpc_err_fail(i, "Unknown Error"); mpc_err_t *e = mpc_err_fail(i, "Unknown Error");
e->state = mpc_state_invalid(); e->state = mpc_state_invalid();
x = mpc_parse_run(i, p, r, &e); x = mpc_parse_run(i, p, r, &e, 0);
if (x) { if (x) {
mpc_err_delete_internal(i, e); mpc_err_delete_internal(i, e);
r->output = mpc_export(i, r->output); r->output = mpc_export(i, r->output);