/* 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))
return false;
}
return treesit_traverse_validate_predicate (XCAR (cdr),
- signal_data);
+ signal_data,
+ recursion_level + 1);
}
else if (BASE_EQ (car, Qor))
{
FOR_EACH_TAIL (cdr)
{
if (!treesit_traverse_validate_predicate (XCAR (cdr),
- signal_data))
+ signal_data,
+ recursion_level + 1))
return false;
}
return true;
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
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 ();
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))
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;