emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 00fba2a4d54 6/7: Add a recursion level limit for tree-sitter sear


From: Yuan Fu
Subject: master 00fba2a4d54 6/7: Add a recursion level limit for tree-sitter search predicates
Date: Fri, 14 Apr 2023 20:04:48 -0400 (EDT)

branch: master
commit 00fba2a4d54cb117ad3176e6633cf2137d52223a
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    Add a recursion level limit for tree-sitter search predicates
    
    * src/treesit.c:
    (treesit_traverse_validate_predicate): Check for recursion level.
    (Ftreesit_search_subtree)
    (Ftreesit_search_forward)
    (Ftreesit_induce_sparse_tree)
    (Ftreesit_node_match_p): Update uses of
    treesit_traverse_validate_predicate.
---
 src/treesit.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/src/treesit.c b/src/treesit.c
index 9b4695b267e..0a289800a0f 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -3155,11 +3155,23 @@ treesit_traverse_child_helper (TSTreeCursor *cursor,
 
 /* Validate the PRED passed to treesit_traverse_match_predicate.  If
    there's an error, set SIGNAL_DATA to something signal accepts, and
-   return false, otherwise return true.  */
+   return false, otherwise return true.  This function also check for
+   recusion levels: we place a arbitrary 100 level limit on recursive
+   predicates.  RECURSION_LEVEL is the current recursion level (that
+   starts at 0), if it goes over 99, return false and set
+   SIGNAL_DATA.  */
 static bool
 treesit_traverse_validate_predicate (Lisp_Object pred,
-                                    Lisp_Object *signal_data)
+                                    Lisp_Object *signal_data,
+                                    ptrdiff_t recursion_level)
 {
+  if (recursion_level > 99)
+    {
+      *signal_data = list1 (build_string ("Predicate recursion level "
+                                         "exceeded: it must not exceed "
+                                         "100 levels"));
+      return false;
+    }
   if (STRINGP (pred))
     return true;
   else if (FUNCTIONP (pred))
@@ -3186,7 +3198,8 @@ treesit_traverse_validate_predicate (Lisp_Object pred,
              return false;
            }
          return treesit_traverse_validate_predicate (XCAR (cdr),
-                                                     signal_data);
+                                                     signal_data,
+                                                     recursion_level + 1);
        }
       else if (BASE_EQ (car, Qor))
        {
@@ -3201,7 +3214,8 @@ treesit_traverse_validate_predicate (Lisp_Object pred,
          FOR_EACH_TAIL (cdr)
            {
              if (!treesit_traverse_validate_predicate (XCAR (cdr),
-                                                       signal_data))
+                                                       signal_data,
+                                                       recursion_level + 1))
                return false;
            }
          return true;
@@ -3399,7 +3413,7 @@ Return the first matched node, or nil if none matches.  
*/)
   CHECK_SYMBOL (backward);
 
   Lisp_Object signal_data = Qnil;
-  if (!treesit_traverse_validate_predicate (predicate, &signal_data))
+  if (!treesit_traverse_validate_predicate (predicate, &signal_data, 0))
     xsignal1 (Qtreesit_invalid_predicate, signal_data);
 
   /* We use a default limit of 1000.  See bug#59426 for the
@@ -3470,7 +3484,7 @@ always traverse leaf nodes first, then upwards.  */)
   CHECK_SYMBOL (backward);
 
   Lisp_Object signal_data = Qnil;
-  if (!treesit_traverse_validate_predicate (predicate, &signal_data))
+  if (!treesit_traverse_validate_predicate (predicate, &signal_data, 0))
     xsignal1 (Qtreesit_invalid_predicate, signal_data);
 
   treesit_initialize ();
@@ -3587,7 +3601,7 @@ a regexp.  */)
   CHECK_TS_NODE (root);
 
   Lisp_Object signal_data = Qnil;
-  if (!treesit_traverse_validate_predicate (predicate, &signal_data))
+  if (!treesit_traverse_validate_predicate (predicate, &signal_data, 0))
     xsignal1 (Qtreesit_invalid_predicate, signal_data);
 
   if (!NILP (process_fn))
@@ -3639,7 +3653,7 @@ if NODE matches PRED, nil otherwise.  */)
   CHECK_TS_NODE (node);
 
   Lisp_Object signal_data = Qnil;
-  if (!treesit_traverse_validate_predicate (predicate, &signal_data))
+  if (!treesit_traverse_validate_predicate (predicate, &signal_data, 0))
     xsignal1 (Qtreesit_invalid_predicate, signal_data);
 
   Lisp_Object parser = XTS_NODE (node)->parser;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]