Skip to content

Commit

Permalink
Check for cmd recursion, as well as callback function recursion.
Browse files Browse the repository at this point in the history
  • Loading branch information
starseeker committed Nov 26, 2024
1 parent 5af5ed5 commit 7f28778
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
13 changes: 13 additions & 0 deletions src/libged/exec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ ged_exec(struct ged *gedp, int argc, const char *argv[])
GED_CK_MAGIC(gedp);
Ged_Internal *gedip = gedp->i->i;
gedip->exec_stack.push(cmdname);
gedip->cmd_recursion_depth_cnt[cmdname]++;

if (gedip->cmd_recursion_depth_cnt[cmdname] > GED_CMD_RECURSION_LIMIT) {
bu_vls_printf(gedp->ged_result_str, "Recursion limit %d exceeded for command %s - aborted. ged_exec call stack:\n", GED_CMD_RECURSION_LIMIT, cmdname.c_str());
std::stack<std::string> lexec_stack = gedip->exec_stack;
while (!lexec_stack.empty()) {
bu_vls_printf(gedp->ged_result_str, "%s\n", lexec_stack.top().c_str());
lexec_stack.pop();
}
return BRLCAD_ERROR;
}

// Check for a pre-exec callback.
bu_clbk_t f = NULL;
Expand All @@ -114,6 +125,7 @@ ged_exec(struct ged *gedp, int argc, const char *argv[])
if (tstr)
bu_log("%s time: %g\n", cmdname.c_str(), (bu_gettime() - start)/1e6);

gedip->cmd_recursion_depth_cnt[cmdname]--;
gedip->exec_stack.pop();
return cret;
}
Expand All @@ -128,6 +140,7 @@ ged_exec(struct ged *gedp, int argc, const char *argv[])
if (tstr)
bu_log("%s time: %g\n", cmdname.c_str(), (bu_gettime() - start)/1e6);

gedip->cmd_recursion_depth_cnt[cmdname]--;
gedip->exec_stack.pop();
return cret;
}
Expand Down
7 changes: 4 additions & 3 deletions src/libged/ged.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,9 +445,9 @@ ged_clbk_exec(struct bu_vls *log, struct ged *gedp, int limit, bu_clbk_t f, int
Ged_Internal *gedip = gedp->i->i;
int rlimit = (limit > 0) ? limit : 1;

gedip->recursion_depth_cnt[f]++;
gedip->clbk_recursion_depth_cnt[f]++;

if (gedip->recursion_depth_cnt[f] > rlimit) {
if (gedip->clbk_recursion_depth_cnt[f] > rlimit) {
if (log) {
// Print out ged_exec call stack that got us here. If the
// recursion is all in callback functions this won't help, but at
Expand All @@ -462,9 +462,10 @@ ged_clbk_exec(struct bu_vls *log, struct ged *gedp, int limit, bu_clbk_t f, int
return BRLCAD_ERROR;
}

// Checks complete - actually run the callback
int ret = (*f)(ac, av, u1, u2);

gedip->recursion_depth_cnt[f]++;
gedip->clbk_recursion_depth_cnt[f]++;

return ret;
}
Expand Down
3 changes: 2 additions & 1 deletion src/libged/ged_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ class Ged_Internal {
std::map<ged_func_ptr, std::pair<bu_clbk_t, void *>> cmd_postrun_clbk;
std::map<ged_func_ptr, std::pair<bu_clbk_t, void *>> cmd_linger_clbk;

std::map<bu_clbk_t, int> recursion_depth_cnt;
std::map<bu_clbk_t, int> clbk_recursion_depth_cnt;
std::map<std::string, int> cmd_recursion_depth_cnt;

std::stack<std::string> exec_stack;

Expand Down

0 comments on commit 7f28778

Please sign in to comment.