Skip to content

MAX_RECURSE_EVAL_NOCHANGE_DEPTH #17490

Open
@hvds

Description

@hvds

This was introduced as 50 by 6bda09f (Yves, 2006-10-04), made compile-time overridable by d56b301 (Rafael, 2007-02-14), bumped to 1000 by 4b196cd (Yves, 2007-02-15), and then dropped to 10 by ba6840f (Yves, 2016-03-06 as part of #14935). There are brief mentions in perlre under (?PARNO) and (??{ expr }):

Recursing deeply without consuming any input string will
also result in a fatal error.  The depth at which that happens is
compiled into perl, so it can be changed with a custom build.
[...]
Executing a postponed regular expression too many times without
consuming any input string will also result in a fatal error.

.. but once we hit a GOSUB it looks like every additional GOSUB or EVAL ("postponed" or not) bumps the count, so as of now we get:

% perl -wle '"foo" =~ m{(?&FOO)(?(DEFINE)(?<FOO>
    (?{1}) (?{1}) (?{1}) (?{1}) (?{1})
    (?{1}) (?{1}) (?{1}) (?{1}) (?{1})
    (?{1})
    foo
))}x'
EVAL without pos change exceeded limit in regex at -e line 1.
% 

This behaviour breaks Regexp::Debugger for quite trivial cases, which is a shame.

I consider it wrong that this recursion check is any more than a warning (as for sub recursion); if there's a good reason for it to be fatal, I think it really must be controllable without having to recompile perl. But the first question is whether it is actually checking the right thing - should it be treating normal (?{...}) evals as a candidate for bumping the recursion depth at all?

@demerphq can you clarify if this check was intended to kill patterns like the above?

Hugo

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions