]> git.neil.brown.name Git - edlib.git/commitdiff
detect and limit recursion
authorNeilBrown <neil@brown.name>
Mon, 12 Jun 2023 22:42:31 +0000 (08:42 +1000)
committerNeilBrown <neil@brown.name>
Wed, 28 Jun 2023 07:51:41 +0000 (17:51 +1000)
If depth of recursion every reaches 100, fail any request.

Signed-off-by: NeilBrown <neil@brown.name>
DOC/TODO.md
core-keymap.c

index 3f90746a33a7b49e80ff54c230c18aef2b20495d..e2baed32a7c3407e47bb9d032d877795c4a57428 100644 (file)
@@ -16,7 +16,7 @@ the file.
 
 ### Small
 
-- [ ] detect and limit recursion.
+- [X] detect and limit recursion.
 - [ ] message-line: use lib-renderline for the one line, so we have
       markup support.
 - [ ] history: Make it possible to search through history. Maybe Alt-p only shows
@@ -69,6 +69,7 @@ Requirements for a v1.0 release
 Core features
 -------------
 
+- [ ] LOG_BT() doesn't see TYPE_pane and TYPE_comm calls.
 - [ ] give every pane a link to root/editor main and use that
       instead of statics.  Then maybe times_up() can use pane_too_long()
 - [ ] mark DEF_CMD structs as const
@@ -94,7 +95,7 @@ Core features
       Efalse probably becomes 0.
 - [ ] send warning message when recursive notification is prohibited.
        editor:notify:Message:broadcast
-- [ ] detect and limit recursion.
+- [X] detect and limit recursion.
       Each call creates a frame, and each pane has a link to recent frame
       If a call happens on a frame with a link, we check that the same
       'key' isn't already active.
index c7f42f53ba4d356a164fd155a0c303fa91a0d812..52420f75c4542eeae24a88af18386b0bc3a7b3a7 100644 (file)
@@ -382,6 +382,7 @@ static struct backtrace {
        const struct cmd_info *ci safe;
        struct backtrace *prev;
 } *backtrace;
+static int backtrace_depth;
 
 static char *mark_info(struct mark *m)
 {
@@ -435,12 +436,24 @@ static int do_comm_call(struct command *comm safe,
        struct backtrace bt;
        int ret;
 
+       if (edlib_timing == 1)
+               return Efail;
+       if (backtrace_depth > 100) {
+               backtrace_depth = 0;
+               LOG("Recursion limit of 100 reached");
+               LOG_BT();
+               backtrace_depth = 100;
+               edlib_timing = 1;
+               return Efail;
+       }
        bt.comm = comm;
        bt.ci = ci;
        bt.prev = backtrace;
        backtrace = &bt;
+       backtrace_depth += 1;
        ret = comm->func(ci);
        backtrace = bt.prev;
+       backtrace_depth -= 1;
        return ret;
 }