aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYuan Fu2023-04-14 13:32:55 -0700
committerYuan Fu2023-04-14 16:54:25 -0700
commit00fba2a4d54cb117ad3176e6633cf2137d52223a (patch)
tree0415c8b021a933dcd98320da8ffe14df973fa20d /src
parent9f777475be5ec2092b7f0ef98be5b1641100beb2 (diff)
downloademacs-00fba2a4d54cb117ad3176e6633cf2137d52223a.tar.gz
emacs-00fba2a4d54cb117ad3176e6633cf2137d52223a.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/treesit.c30
1 files 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,
3155 3155
3156/* Validate the PRED passed to treesit_traverse_match_predicate. If 3156/* Validate the PRED passed to treesit_traverse_match_predicate. If
3157 there's an error, set SIGNAL_DATA to something signal accepts, and 3157 there's an error, set SIGNAL_DATA to something signal accepts, and
3158 return false, otherwise return true. */ 3158 return false, otherwise return true. This function also check for
3159 recusion levels: we place a arbitrary 100 level limit on recursive
3160 predicates. RECURSION_LEVEL is the current recursion level (that
3161 starts at 0), if it goes over 99, return false and set
3162 SIGNAL_DATA. */
3159static bool 3163static bool
3160treesit_traverse_validate_predicate (Lisp_Object pred, 3164treesit_traverse_validate_predicate (Lisp_Object pred,
3161 Lisp_Object *signal_data) 3165 Lisp_Object *signal_data,
3166 ptrdiff_t recursion_level)
3162{ 3167{
3168 if (recursion_level > 99)
3169 {
3170 *signal_data = list1 (build_string ("Predicate recursion level "
3171 "exceeded: it must not exceed "
3172 "100 levels"));
3173 return false;
3174 }
3163 if (STRINGP (pred)) 3175 if (STRINGP (pred))
3164 return true; 3176 return true;
3165 else if (FUNCTIONP (pred)) 3177 else if (FUNCTIONP (pred))
@@ -3186,7 +3198,8 @@ treesit_traverse_validate_predicate (Lisp_Object pred,
3186 return false; 3198 return false;
3187 } 3199 }
3188 return treesit_traverse_validate_predicate (XCAR (cdr), 3200 return treesit_traverse_validate_predicate (XCAR (cdr),
3189 signal_data); 3201 signal_data,
3202 recursion_level + 1);
3190 } 3203 }
3191 else if (BASE_EQ (car, Qor)) 3204 else if (BASE_EQ (car, Qor))
3192 { 3205 {
@@ -3201,7 +3214,8 @@ treesit_traverse_validate_predicate (Lisp_Object pred,
3201 FOR_EACH_TAIL (cdr) 3214 FOR_EACH_TAIL (cdr)
3202 { 3215 {
3203 if (!treesit_traverse_validate_predicate (XCAR (cdr), 3216 if (!treesit_traverse_validate_predicate (XCAR (cdr),
3204 signal_data)) 3217 signal_data,
3218 recursion_level + 1))
3205 return false; 3219 return false;
3206 } 3220 }
3207 return true; 3221 return true;
@@ -3399,7 +3413,7 @@ Return the first matched node, or nil if none matches. */)
3399 CHECK_SYMBOL (backward); 3413 CHECK_SYMBOL (backward);
3400 3414
3401 Lisp_Object signal_data = Qnil; 3415 Lisp_Object signal_data = Qnil;
3402 if (!treesit_traverse_validate_predicate (predicate, &signal_data)) 3416 if (!treesit_traverse_validate_predicate (predicate, &signal_data, 0))
3403 xsignal1 (Qtreesit_invalid_predicate, signal_data); 3417 xsignal1 (Qtreesit_invalid_predicate, signal_data);
3404 3418
3405 /* We use a default limit of 1000. See bug#59426 for the 3419 /* We use a default limit of 1000. See bug#59426 for the
@@ -3470,7 +3484,7 @@ always traverse leaf nodes first, then upwards. */)
3470 CHECK_SYMBOL (backward); 3484 CHECK_SYMBOL (backward);
3471 3485
3472 Lisp_Object signal_data = Qnil; 3486 Lisp_Object signal_data = Qnil;
3473 if (!treesit_traverse_validate_predicate (predicate, &signal_data)) 3487 if (!treesit_traverse_validate_predicate (predicate, &signal_data, 0))
3474 xsignal1 (Qtreesit_invalid_predicate, signal_data); 3488 xsignal1 (Qtreesit_invalid_predicate, signal_data);
3475 3489
3476 treesit_initialize (); 3490 treesit_initialize ();
@@ -3587,7 +3601,7 @@ a regexp. */)
3587 CHECK_TS_NODE (root); 3601 CHECK_TS_NODE (root);
3588 3602
3589 Lisp_Object signal_data = Qnil; 3603 Lisp_Object signal_data = Qnil;
3590 if (!treesit_traverse_validate_predicate (predicate, &signal_data)) 3604 if (!treesit_traverse_validate_predicate (predicate, &signal_data, 0))
3591 xsignal1 (Qtreesit_invalid_predicate, signal_data); 3605 xsignal1 (Qtreesit_invalid_predicate, signal_data);
3592 3606
3593 if (!NILP (process_fn)) 3607 if (!NILP (process_fn))
@@ -3639,7 +3653,7 @@ if NODE matches PRED, nil otherwise. */)
3639 CHECK_TS_NODE (node); 3653 CHECK_TS_NODE (node);
3640 3654
3641 Lisp_Object signal_data = Qnil; 3655 Lisp_Object signal_data = Qnil;
3642 if (!treesit_traverse_validate_predicate (predicate, &signal_data)) 3656 if (!treesit_traverse_validate_predicate (predicate, &signal_data, 0))
3643 xsignal1 (Qtreesit_invalid_predicate, signal_data); 3657 xsignal1 (Qtreesit_invalid_predicate, signal_data);
3644 3658
3645 Lisp_Object parser = XTS_NODE (node)->parser; 3659 Lisp_Object parser = XTS_NODE (node)->parser;