Change "limit recursion" to "limit depth" in code and build systems because the

old name, which is retained as a synonym for the moment, is no longer 
appropriate.
This commit is contained in:
Philip.Hazel 2017-03-12 13:47:01 +00:00
parent 04da0725f3
commit 88db1be123
22 changed files with 217 additions and 171 deletions

View File

@ -146,8 +146,8 @@ SET(PCRE2_PARENS_NEST_LIMIT "250" CACHE STRING
SET(PCRE2_MATCH_LIMIT "10000000" CACHE STRING SET(PCRE2_MATCH_LIMIT "10000000" CACHE STRING
"Default limit on internal looping. See MATCH_LIMIT in config.h.in for details.") "Default limit on internal looping. See MATCH_LIMIT in config.h.in for details.")
SET(PCRE2_MATCH_LIMIT_RECURSION "MATCH_LIMIT" CACHE STRING SET(PCRE2_MATCH_LIMIT_DEPTH "MATCH_LIMIT" CACHE STRING
"Default limit on internal recursion. See MATCH_LIMIT_RECURSION in config.h.in for details.") "Default limit on internal depth of search. See MATCH_LIMIT_DEPTH in config.h.in for details.")
SET(PCRE2GREP_BUFSIZE "20480" CACHE STRING SET(PCRE2GREP_BUFSIZE "20480" CACHE STRING
"Buffer starting size parameter for pcre2grep. See PCRE2GREP_BUFSIZE in config.h.in for details.") "Buffer starting size parameter for pcre2grep. See PCRE2GREP_BUFSIZE in config.h.in for details.")
@ -766,7 +766,7 @@ IF(PCRE2_SHOW_REPORT)
MESSAGE(STATUS " Internal link size .............. : ${PCRE2_LINK_SIZE}") MESSAGE(STATUS " Internal link size .............. : ${PCRE2_LINK_SIZE}")
MESSAGE(STATUS " Parentheses nest limit .......... : ${PCRE2_PARENS_NEST_LIMIT}") MESSAGE(STATUS " Parentheses nest limit .......... : ${PCRE2_PARENS_NEST_LIMIT}")
MESSAGE(STATUS " Match limit ..................... : ${PCRE2_MATCH_LIMIT}") MESSAGE(STATUS " Match limit ..................... : ${PCRE2_MATCH_LIMIT}")
MESSAGE(STATUS " Match limit recursion ........... : ${PCRE2_MATCH_LIMIT_RECURSION}") MESSAGE(STATUS " Match depth limit ............... : ${PCRE2_MATCH_LIMIT_DEPTH}")
MESSAGE(STATUS " Build shared libs ............... : ${BUILD_SHARED_LIBS}") MESSAGE(STATUS " Build shared libs ............... : ${BUILD_SHARED_LIBS}")
MESSAGE(STATUS " Build static libs ............... : ${BUILD_STATIC_LIBS}") MESSAGE(STATUS " Build static libs ............... : ${BUILD_STATIC_LIBS}")
MESSAGE(STATUS " Build pcre2grep ................. : ${PCRE2_BUILD_PCRE2GREP}") MESSAGE(STATUS " Build pcre2grep ................. : ${PCRE2_BUILD_PCRE2GREP}")

View File

@ -29,13 +29,20 @@ released code, but are noted here for the record.
crash. A vector on the heap is now set up at the start of matching if the crash. A vector on the heap is now set up at the start of matching if the
vector on the stack is not big enough to handle at least 10 frames. vector on the stack is not big enough to handle at least 10 frames.
Fixes oss-fuzz issue 783. Fixes oss-fuzz issue 783.
2. Now that pcre2_match() no longer uses recursive function calls (see above),
the "match limit recursion" value seems misnamed. It still exists, and limits
the depth of tree that is searched. To avoid future confusion, it has been
renamed as "depth limit" in all relevant places (--with-depth-limit,
(*LIMIT_DEPTH), pcre2_set_depth_limit(), etc) but the old names are still
available for backwards compatibility.
2. Hardened pcre2test so as to reduce the number of bugs reported by fuzzers: 3. Hardened pcre2test so as to reduce the number of bugs reported by fuzzers:
(a) Check for malloc failures when getting memory for the ovector (POSIX) or (a) Check for malloc failures when getting memory for the ovector (POSIX) or
the match data block (non-POSIX). the match data block (non-POSIX).
3. In the 32-bit library in non-UTF mode, an attempt to find a Unicode property 4. In the 32-bit library in non-UTF mode, an attempt to find a Unicode property
for a character with a code point greater than 0x10ffff (the Unicode maximum) for a character with a code point greater than 0x10ffff (the Unicode maximum)
caused a crash. caused a crash.

View File

@ -269,18 +269,22 @@ AC_ARG_WITH(match-limit,
[default limit on internal looping (default=10000000)]), [default limit on internal looping (default=10000000)]),
, with_match_limit=10000000) , with_match_limit=10000000)
# Handle --with-match-limit_recursion=N # Handle --with-match-limit-depth=N
# Recognize old synonym --with-match-limit-recursion
# #
# Note: In config.h, the default is to define MATCH_LIMIT_RECURSION # Note: In config.h, the default is to define MATCH_LIMIT_DEPTH symbolically as
# symbolically as MATCH_LIMIT, which in turn is defined to be some numeric # MATCH_LIMIT, which in turn is defined to be some numeric value (e.g.
# value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some # 10000000). MATCH_LIMIT_DEPTH can otherwise be set to some different numeric
# different numeric value (or even the same numeric value as MATCH_LIMIT, # value (or even the same numeric value as MATCH_LIMIT, though no longer
# though no longer defined in terms of the latter). # defined in terms of the latter).
# #
AC_ARG_WITH(match-limit-recursion, AC_ARG_WITH(match-limit-depth,
AS_HELP_STRING([--with-match-limit-recursion=N], AS_HELP_STRING([--with-match-limit-depth=N],
[default limit on internal recursion (default=MATCH_LIMIT)]), [default limit on match tree depth (default=MATCH_LIMIT)]),
, with_match_limit_recursion=MATCH_LIMIT) , with_match_limit_depth=MATCH_LIMIT)
AC_ARG_WITH(match-limit-recursion,,
, with_match_limit_recursion=UNSET)
# Handle --enable-valgrind # Handle --enable-valgrind
AC_ARG_ENABLE(valgrind, AC_ARG_ENABLE(valgrind,
@ -299,7 +303,7 @@ AC_ARG_ENABLE(fuzz_support,
AS_HELP_STRING([--enable-fuzz-support], AS_HELP_STRING([--enable-fuzz-support],
[enable fuzzer support]), [enable fuzzer support]),
, enable_fuzz_support=no) , enable_fuzz_support=no)
# Handle --disable-stack-for-recursion # Handle --disable-stack-for-recursion
# This option became obsolete at release 10.30. # This option became obsolete at release 10.30.
AC_ARG_ENABLE(stack-for-recursion,, AC_ARG_ENABLE(stack-for-recursion,,
@ -683,14 +687,29 @@ AC_DEFINE_UNQUOTED([MATCH_LIMIT], [$with_match_limit], [
to determine that they do not match. The default is set very large so that it to determine that they do not match. The default is set very large so that it
does not accidentally catch legitimate cases.]) does not accidentally catch legitimate cases.])
AC_DEFINE_UNQUOTED([MATCH_LIMIT_RECURSION], [$with_match_limit_recursion], [ # --with-match-limit-recursion is an obsolete synonym for --with-match-limit-depth
if test "$with_match_limit_recursion" != "UNSET"; then
cat <<EOF
WARNING: --with-match-limit-recursion is an obsolete option. Please use
--with-match-limit-depth in future. If both are set, --with-match-limit-depth
will be used.
EOF
if test "$with_match_limit_depth" = "MATCH_LIMIT"; then
with_match_limit_depth=$with_match_limit_recursion
fi
fi
AC_DEFINE_UNQUOTED([MATCH_LIMIT_DEPTH], [$with_match_limit_depth], [
The above limit applies to all backtracks, whether or not they are nested. In The above limit applies to all backtracks, whether or not they are nested. In
some environments it is desirable to limit the nesting of backtracking more some environments it is desirable to limit the nesting of backtracking (that
strictly, in order to restrict the maximum amount of heap memory that is is, the depth of tree that is searched) more strictly, in order to restrict
used. The value of MATCH_LIMIT_RECURSION provides this facility. To have any the maximum amount of heap memory that is used. The value of
useful effect, it must be less than the value of MATCH_LIMIT. The default is MATCH_LIMIT_DEPTH provides this facility. To have any useful effect, it must
to use the same value as MATCH_LIMIT. There is a runtime method for setting a be less than the value of MATCH_LIMIT. The default is to use the same value
different limit.]) as MATCH_LIMIT. There is a runtime method for setting a different limit.])
AC_DEFINE([MAX_NAME_SIZE], [32], [ AC_DEFINE([MAX_NAME_SIZE], [32], [
This limit is parameterized just in case anybody ever wants to This limit is parameterized just in case anybody ever wants to
@ -953,7 +972,7 @@ $PACKAGE-$VERSION configuration summary:
Internal link size ................. : ${with_link_size} Internal link size ................. : ${with_link_size}
Nested parentheses limit ........... : ${with_parens_nest_limit} Nested parentheses limit ........... : ${with_parens_nest_limit}
Match limit ........................ : ${with_match_limit} Match limit ........................ : ${with_match_limit}
Match limit recursion .............. : ${with_match_limit_recursion} Match depth limit .................. : ${with_match_limit_depth}
Build shared libs .................. : ${enable_shared} Build shared libs .................. : ${enable_shared}
Build static libs .................. : ${enable_static} Build static libs .................. : ${enable_static}
Use JIT in pcre2grep ............... : ${enable_pcre2grep_jit} Use JIT in pcre2grep ............... : ${enable_pcre2grep_jit}

View File

@ -152,12 +152,13 @@ sure both macros are undefined; an emulation function will then be used. */
/* The above limit applies to all backtracks, whether or not they are nested. /* The above limit applies to all backtracks, whether or not they are nested.
In some environments it is desirable to limit the nesting of backtracking In some environments it is desirable to limit the nesting of backtracking
more strictly, in order to restrict the maximum amount of heap memory that (that is, the depth of tree that is searched) more strictly, in order to
is used. The value of MATCH_LIMIT_RECURSION provides this facility. To have restrict the maximum amount of heap memory that is used. The value of
any useful effect, it must be less than the value of MATCH_LIMIT. The MATCH_LIMIT_DEPTH provides this facility. To have any useful effect, it
default is to use the same value as MATCH_LIMIT. There is a runtime method must be less than the value of MATCH_LIMIT. The default is to use the same
for setting a different limit. */ value as MATCH_LIMIT. There is a runtime method for setting a different
#undef MATCH_LIMIT_RECURSION limit. */
#undef MATCH_LIMIT_DEPTH
/* This limit is parameterized just in case anybody ever wants to change it. /* This limit is parameterized just in case anybody ever wants to change it.
Care must be taken if it is increased, because it guards against integer Care must be taken if it is increased, because it guards against integer

View File

@ -5,7 +5,7 @@
/* This is the public header file for the PCRE library, second API, to be /* This is the public header file for the PCRE library, second API, to be
#included by applications that call PCRE2 functions. #included by applications that call PCRE2 functions.
Copyright (c) 2016 University of Cambridge Copyright (c) 2016-2017 University of Cambridge
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -256,7 +256,8 @@ numbers must not be changed. */
#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50) #define PCRE2_ERROR_NOUNIQUESUBSTRING (-50)
#define PCRE2_ERROR_NULL (-51) #define PCRE2_ERROR_NULL (-51)
#define PCRE2_ERROR_RECURSELOOP (-52) #define PCRE2_ERROR_RECURSELOOP (-52)
#define PCRE2_ERROR_RECURSIONLIMIT (-53) #define PCRE2_ERROR_DEPTHLIMIT (-53)
#define PCRE2_ERROR_RECURSIONLIMIT (-53) /* Obsolete synonym */
#define PCRE2_ERROR_UNAVAILABLE (-54) #define PCRE2_ERROR_UNAVAILABLE (-54)
#define PCRE2_ERROR_UNSET (-55) #define PCRE2_ERROR_UNSET (-55)
#define PCRE2_ERROR_BADOFFSETLIMIT (-56) #define PCRE2_ERROR_BADOFFSETLIMIT (-56)
@ -290,7 +291,8 @@ numbers must not be changed. */
#define PCRE2_INFO_NAMEENTRYSIZE 18 #define PCRE2_INFO_NAMEENTRYSIZE 18
#define PCRE2_INFO_NAMETABLE 19 #define PCRE2_INFO_NAMETABLE 19
#define PCRE2_INFO_NEWLINE 20 #define PCRE2_INFO_NEWLINE 20
#define PCRE2_INFO_RECURSIONLIMIT 21 #define PCRE2_INFO_DEPTHLIMIT 21
#define PCRE2_INFO_RECURSIONLIMIT 21 /* Obsolete synonym */
#define PCRE2_INFO_SIZE 22 #define PCRE2_INFO_SIZE 22
#define PCRE2_INFO_HASBACKSLASHC 23 #define PCRE2_INFO_HASBACKSLASHC 23
@ -303,7 +305,8 @@ numbers must not be changed. */
#define PCRE2_CONFIG_MATCHLIMIT 4 #define PCRE2_CONFIG_MATCHLIMIT 4
#define PCRE2_CONFIG_NEWLINE 5 #define PCRE2_CONFIG_NEWLINE 5
#define PCRE2_CONFIG_PARENSLIMIT 6 #define PCRE2_CONFIG_PARENSLIMIT 6
#define PCRE2_CONFIG_RECURSIONLIMIT 7 #define PCRE2_CONFIG_DEPTHLIMIT 7
#define PCRE2_CONFIG_RECURSIONLIMIT 7 /* Obsolete synonym */
#define PCRE2_CONFIG_STACKRECURSE 8 /* Obsolete */ #define PCRE2_CONFIG_STACKRECURSE 8 /* Obsolete */
#define PCRE2_CONFIG_UNICODE 9 #define PCRE2_CONFIG_UNICODE 9
#define PCRE2_CONFIG_UNICODE_VERSION 10 #define PCRE2_CONFIG_UNICODE_VERSION 10
@ -445,12 +448,12 @@ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_callout(pcre2_match_context *, \ pcre2_set_callout(pcre2_match_context *, \
int (*)(pcre2_callout_block *, void *), void *); \ int (*)(pcre2_callout_block *, void *), void *); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_depth_limit(pcre2_match_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_match_limit(pcre2_match_context *, uint32_t); \ pcre2_set_match_limit(pcre2_match_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_offset_limit(pcre2_match_context *, PCRE2_SIZE); \ pcre2_set_offset_limit(pcre2_match_context *, PCRE2_SIZE); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_recursion_memory_management(pcre2_match_context *, \ pcre2_set_recursion_memory_management(pcre2_match_context *, \
void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *); void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *);
@ -670,13 +673,12 @@ pcre2_compile are called by application code. */
#define pcre2_set_callout PCRE2_SUFFIX(pcre2_set_callout_) #define pcre2_set_callout PCRE2_SUFFIX(pcre2_set_callout_)
#define pcre2_set_character_tables PCRE2_SUFFIX(pcre2_set_character_tables_) #define pcre2_set_character_tables PCRE2_SUFFIX(pcre2_set_character_tables_)
#define pcre2_set_compile_recursion_guard PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_) #define pcre2_set_compile_recursion_guard PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_)
#define pcre2_set_depth_limit PCRE2_SUFFIX(pcre2_set_depth_limit_)
#define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_) #define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_)
#define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_) #define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_)
#define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) #define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_)
#define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) #define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_)
#define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_) #define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_)
#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_)
#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)
#define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_) #define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_)
#define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_) #define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_)
#define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_) #define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_)
@ -690,6 +692,11 @@ pcre2_compile are called by application code. */
#define pcre2_substring_nametable_scan PCRE2_SUFFIX(pcre2_substring_nametable_scan_) #define pcre2_substring_nametable_scan PCRE2_SUFFIX(pcre2_substring_nametable_scan_)
#define pcre2_substring_number_from_name PCRE2_SUFFIX(pcre2_substring_number_from_name_) #define pcre2_substring_number_from_name PCRE2_SUFFIX(pcre2_substring_number_from_name_)
/* Keep this old function name for backwards compatibility */
#define pcre2_set_recursion_limit pcre2_set_depth_limit
/* Keep this obsolete function for backwards compatibility: it is now a noop. */
#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)
/* Now generate all three sets of width-specific structures and function /* Now generate all three sets of width-specific structures and function
prototypes. */ prototypes. */

View File

@ -5,7 +5,7 @@
/* This is the public header file for the PCRE library, second API, to be /* This is the public header file for the PCRE library, second API, to be
#included by applications that call PCRE2 functions. #included by applications that call PCRE2 functions.
Copyright (c) 2016 University of Cambridge Copyright (c) 2016-2017 University of Cambridge
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -256,7 +256,8 @@ numbers must not be changed. */
#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50) #define PCRE2_ERROR_NOUNIQUESUBSTRING (-50)
#define PCRE2_ERROR_NULL (-51) #define PCRE2_ERROR_NULL (-51)
#define PCRE2_ERROR_RECURSELOOP (-52) #define PCRE2_ERROR_RECURSELOOP (-52)
#define PCRE2_ERROR_RECURSIONLIMIT (-53) #define PCRE2_ERROR_DEPTHLIMIT (-53)
#define PCRE2_ERROR_RECURSIONLIMIT (-53) /* Obsolete synonym */
#define PCRE2_ERROR_UNAVAILABLE (-54) #define PCRE2_ERROR_UNAVAILABLE (-54)
#define PCRE2_ERROR_UNSET (-55) #define PCRE2_ERROR_UNSET (-55)
#define PCRE2_ERROR_BADOFFSETLIMIT (-56) #define PCRE2_ERROR_BADOFFSETLIMIT (-56)
@ -290,7 +291,8 @@ numbers must not be changed. */
#define PCRE2_INFO_NAMEENTRYSIZE 18 #define PCRE2_INFO_NAMEENTRYSIZE 18
#define PCRE2_INFO_NAMETABLE 19 #define PCRE2_INFO_NAMETABLE 19
#define PCRE2_INFO_NEWLINE 20 #define PCRE2_INFO_NEWLINE 20
#define PCRE2_INFO_RECURSIONLIMIT 21 #define PCRE2_INFO_DEPTHLIMIT 21
#define PCRE2_INFO_RECURSIONLIMIT 21 /* Obsolete synonym */
#define PCRE2_INFO_SIZE 22 #define PCRE2_INFO_SIZE 22
#define PCRE2_INFO_HASBACKSLASHC 23 #define PCRE2_INFO_HASBACKSLASHC 23
@ -303,7 +305,8 @@ numbers must not be changed. */
#define PCRE2_CONFIG_MATCHLIMIT 4 #define PCRE2_CONFIG_MATCHLIMIT 4
#define PCRE2_CONFIG_NEWLINE 5 #define PCRE2_CONFIG_NEWLINE 5
#define PCRE2_CONFIG_PARENSLIMIT 6 #define PCRE2_CONFIG_PARENSLIMIT 6
#define PCRE2_CONFIG_RECURSIONLIMIT 7 #define PCRE2_CONFIG_DEPTHLIMIT 7
#define PCRE2_CONFIG_RECURSIONLIMIT 7 /* Obsolete synonym */
#define PCRE2_CONFIG_STACKRECURSE 8 /* Obsolete */ #define PCRE2_CONFIG_STACKRECURSE 8 /* Obsolete */
#define PCRE2_CONFIG_UNICODE 9 #define PCRE2_CONFIG_UNICODE 9
#define PCRE2_CONFIG_UNICODE_VERSION 10 #define PCRE2_CONFIG_UNICODE_VERSION 10
@ -445,12 +448,12 @@ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_callout(pcre2_match_context *, \ pcre2_set_callout(pcre2_match_context *, \
int (*)(pcre2_callout_block *, void *), void *); \ int (*)(pcre2_callout_block *, void *), void *); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_depth_limit(pcre2_match_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_match_limit(pcre2_match_context *, uint32_t); \ pcre2_set_match_limit(pcre2_match_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_offset_limit(pcre2_match_context *, PCRE2_SIZE); \ pcre2_set_offset_limit(pcre2_match_context *, PCRE2_SIZE); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_recursion_memory_management(pcre2_match_context *, \ pcre2_set_recursion_memory_management(pcre2_match_context *, \
void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *); void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *);
@ -670,13 +673,12 @@ pcre2_compile are called by application code. */
#define pcre2_set_callout PCRE2_SUFFIX(pcre2_set_callout_) #define pcre2_set_callout PCRE2_SUFFIX(pcre2_set_callout_)
#define pcre2_set_character_tables PCRE2_SUFFIX(pcre2_set_character_tables_) #define pcre2_set_character_tables PCRE2_SUFFIX(pcre2_set_character_tables_)
#define pcre2_set_compile_recursion_guard PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_) #define pcre2_set_compile_recursion_guard PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_)
#define pcre2_set_depth_limit PCRE2_SUFFIX(pcre2_set_depth_limit_)
#define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_) #define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_)
#define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_) #define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_)
#define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) #define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_)
#define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) #define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_)
#define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_) #define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_)
#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_)
#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)
#define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_) #define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_)
#define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_) #define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_)
#define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_) #define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_)
@ -690,6 +692,11 @@ pcre2_compile are called by application code. */
#define pcre2_substring_nametable_scan PCRE2_SUFFIX(pcre2_substring_nametable_scan_) #define pcre2_substring_nametable_scan PCRE2_SUFFIX(pcre2_substring_nametable_scan_)
#define pcre2_substring_number_from_name PCRE2_SUFFIX(pcre2_substring_number_from_name_) #define pcre2_substring_number_from_name PCRE2_SUFFIX(pcre2_substring_number_from_name_)
/* Keep this old function name for backwards compatibility */
#define pcre2_set_recursion_limit pcre2_set_depth_limit
/* Keep this obsolete function for backwards compatibility: it is now a noop. */
#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)
/* Now generate all three sets of width-specific structures and function /* Now generate all three sets of width-specific structures and function
prototypes. */ prototypes. */

View File

@ -728,7 +728,7 @@ enum { PSO_OPT, /* Value is an option bit */
PSO_NL, /* Value is a newline type */ PSO_NL, /* Value is a newline type */
PSO_BSR, /* Value is a \R type */ PSO_BSR, /* Value is a \R type */
PSO_LIMM, /* Read integer value for match limit */ PSO_LIMM, /* Read integer value for match limit */
PSO_LIMR }; /* Read integer value for recursion limit */ PSO_LIMD }; /* Read integer value for depth limit */
typedef struct pso { typedef struct pso {
const uint8_t *name; const uint8_t *name;
@ -750,7 +750,8 @@ static pso pso_list[] = {
{ (uint8_t *)STRING_NO_JIT_RIGHTPAR, 7, PSO_FLG, PCRE2_NOJIT }, { (uint8_t *)STRING_NO_JIT_RIGHTPAR, 7, PSO_FLG, PCRE2_NOJIT },
{ (uint8_t *)STRING_NO_START_OPT_RIGHTPAR, 13, PSO_OPT, PCRE2_NO_START_OPTIMIZE }, { (uint8_t *)STRING_NO_START_OPT_RIGHTPAR, 13, PSO_OPT, PCRE2_NO_START_OPTIMIZE },
{ (uint8_t *)STRING_LIMIT_MATCH_EQ, 12, PSO_LIMM, 0 }, { (uint8_t *)STRING_LIMIT_MATCH_EQ, 12, PSO_LIMM, 0 },
{ (uint8_t *)STRING_LIMIT_RECURSION_EQ, 16, PSO_LIMR, 0 }, { (uint8_t *)STRING_LIMIT_DEPTH_EQ, 12, PSO_LIMD, 0 },
{ (uint8_t *)STRING_LIMIT_RECURSION_EQ, 16, PSO_LIMD, 0 },
{ (uint8_t *)STRING_CR_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_CR }, { (uint8_t *)STRING_CR_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_CR },
{ (uint8_t *)STRING_LF_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_LF }, { (uint8_t *)STRING_LF_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_LF },
{ (uint8_t *)STRING_CRLF_RIGHTPAR, 5, PSO_NL, PCRE2_NEWLINE_CRLF }, { (uint8_t *)STRING_CRLF_RIGHTPAR, 5, PSO_NL, PCRE2_NEWLINE_CRLF },
@ -8823,7 +8824,7 @@ uint32_t setflags = 0; /* NL and BSR set flags */
uint32_t skipatstart; /* When checking (*UTF) etc */ uint32_t skipatstart; /* When checking (*UTF) etc */
uint32_t limit_match = UINT32_MAX; /* Unset match limits */ uint32_t limit_match = UINT32_MAX; /* Unset match limits */
uint32_t limit_recursion = UINT32_MAX; uint32_t limit_depth = UINT32_MAX;
int newline = 0; /* Unset; can be set by the pattern */ int newline = 0; /* Unset; can be set by the pattern */
int bsr = 0; /* Unset; can be set by the pattern */ int bsr = 0; /* Unset; can be set by the pattern */
@ -8994,7 +8995,7 @@ while (patlen - skipatstart >= 2 &&
break; break;
case PSO_LIMM: case PSO_LIMM:
case PSO_LIMR: case PSO_LIMD:
c = 0; c = 0;
pp = skipatstart; pp = skipatstart;
if (!IS_DIGIT(ptr[pp])) if (!IS_DIGIT(ptr[pp]))
@ -9015,7 +9016,7 @@ while (patlen - skipatstart >= 2 &&
goto HAD_EARLY_ERROR; goto HAD_EARLY_ERROR;
} }
if (p->type == PSO_LIMM) limit_match = c; if (p->type == PSO_LIMM) limit_match = c;
else limit_recursion = c; else limit_depth = c;
skipatstart += pp - skipatstart; skipatstart += pp - skipatstart;
break; break;
} }
@ -9258,7 +9259,7 @@ re->compile_options = options;
re->overall_options = cb.external_options; re->overall_options = cb.external_options;
re->flags = PCRE2_CODE_UNIT_WIDTH/8 | cb.external_flags | setflags; re->flags = PCRE2_CODE_UNIT_WIDTH/8 | cb.external_flags | setflags;
re->limit_match = limit_match; re->limit_match = limit_match;
re->limit_recursion = limit_recursion; re->limit_depth = limit_depth;
re->first_codeunit = 0; re->first_codeunit = 0;
re->last_codeunit = 0; re->last_codeunit = 0;
re->bsr_convention = bsr; re->bsr_convention = bsr;

View File

@ -87,9 +87,9 @@ if (where == NULL) /* Requests a length */
case PCRE2_CONFIG_JIT: case PCRE2_CONFIG_JIT:
case PCRE2_CONFIG_LINKSIZE: case PCRE2_CONFIG_LINKSIZE:
case PCRE2_CONFIG_MATCHLIMIT: case PCRE2_CONFIG_MATCHLIMIT:
case PCRE2_CONFIG_DEPTHLIMIT:
case PCRE2_CONFIG_NEWLINE: case PCRE2_CONFIG_NEWLINE:
case PCRE2_CONFIG_PARENSLIMIT: case PCRE2_CONFIG_PARENSLIMIT:
case PCRE2_CONFIG_RECURSIONLIMIT:
case PCRE2_CONFIG_STACKRECURSE: /* Obsolete */ case PCRE2_CONFIG_STACKRECURSE: /* Obsolete */
case PCRE2_CONFIG_UNICODE: case PCRE2_CONFIG_UNICODE:
return sizeof(uint32_t); return sizeof(uint32_t);
@ -143,6 +143,10 @@ switch (what)
*((uint32_t *)where) = MATCH_LIMIT; *((uint32_t *)where) = MATCH_LIMIT;
break; break;
case PCRE2_CONFIG_DEPTHLIMIT:
*((uint32_t *)where) = MATCH_LIMIT_DEPTH;
break;
case PCRE2_CONFIG_NEWLINE: case PCRE2_CONFIG_NEWLINE:
*((uint32_t *)where) = NEWLINE_DEFAULT; *((uint32_t *)where) = NEWLINE_DEFAULT;
break; break;
@ -151,10 +155,6 @@ switch (what)
*((uint32_t *)where) = PARENS_NEST_LIMIT; *((uint32_t *)where) = PARENS_NEST_LIMIT;
break; break;
case PCRE2_CONFIG_RECURSIONLIMIT:
*((uint32_t *)where) = MATCH_LIMIT_RECURSION;
break;
/* This is now obsolete. The stack is no longer used via recursion for /* This is now obsolete. The stack is no longer used via recursion for
handling backtracking in pcre2_match(). */ handling backtracking in pcre2_match(). */

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016 University of Cambridge New API code Copyright (c) 2016-2017 University of Cambridge
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -169,7 +169,7 @@ const pcre2_match_context PRIV(default_match_context) = {
NULL, NULL,
PCRE2_UNSET, /* Offset limit */ PCRE2_UNSET, /* Offset limit */
MATCH_LIMIT, MATCH_LIMIT,
MATCH_LIMIT_RECURSION }; MATCH_LIMIT_DEPTH };
/* The create function copies the default into the new memory, but must /* The create function copies the default into the new memory, but must
override the default memory handling functions if a gcontext was provided. */ override the default memory handling functions if a gcontext was provided. */
@ -354,16 +354,16 @@ return 0;
} }
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit) pcre2_set_depth_limit(pcre2_match_context *mcontext, uint32_t limit)
{ {
mcontext->offset_limit = limit; mcontext->depth_limit = limit;
return 0; return 0;
} }
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit) pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit)
{ {
mcontext->recursion_limit = limit; mcontext->offset_limit = limit;
return 0; return 0;
} }

View File

@ -400,7 +400,7 @@ BOOL utf = FALSE;
BOOL reset_could_continue = FALSE; BOOL reset_could_continue = FALSE;
if (rlevel++ > mb->match_limit_recursion) return PCRE2_ERROR_RECURSIONLIMIT; if (rlevel++ > mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;
offsetcount &= (uint32_t)(-2); /* Round down */ offsetcount &= (uint32_t)(-2); /* Round down */
wscount -= 2; wscount -= 2;
@ -3215,7 +3215,7 @@ if (mcontext == NULL)
{ {
mb->callout = NULL; mb->callout = NULL;
mb->memctl = re->memctl; mb->memctl = re->memctl;
mb->match_limit_recursion = PRIV(default_match_context).recursion_limit; mb->match_limit_depth = PRIV(default_match_context).depth_limit;
} }
else else
{ {
@ -3228,10 +3228,10 @@ else
mb->callout = mcontext->callout; mb->callout = mcontext->callout;
mb->callout_data = mcontext->callout_data; mb->callout_data = mcontext->callout_data;
mb->memctl = mcontext->memctl; mb->memctl = mcontext->memctl;
mb->match_limit_recursion = mcontext->recursion_limit; mb->match_limit_depth = mcontext->depth_limit;
} }
if (mb->match_limit_recursion > re->limit_recursion) if (mb->match_limit_depth > re->limit_depth)
mb->match_limit_recursion = re->limit_recursion; mb->match_limit_depth = re->limit_depth;
mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) +
re->name_count * re->name_entry_size; re->name_count * re->name_entry_size;

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016 University of Cambridge New API code Copyright (c) 2016-2017 University of Cambridge
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -244,7 +244,7 @@ static const unsigned char match_error_texts[] =
"non-unique substring name\0" "non-unique substring name\0"
"NULL argument passed\0" "NULL argument passed\0"
"nested recursion at the same subject position\0" "nested recursion at the same subject position\0"
"recursion limit exceeded\0" "matching depth limit exceeded\0"
"requested value is not available\0" "requested value is not available\0"
/* 55 */ /* 55 */
"requested value is not set\0" "requested value is not set\0"

View File

@ -141,8 +141,8 @@ for (i = 0; i < 2; i++)
int j; int j;
uint32_t save_match_options = match_options; uint32_t save_match_options = match_options;
/* Create match data and context blocks only when we first need them. Set /* Create match data and context blocks only when we first need them. Set
low match and recursion limits to avoid wasting too much searching large low match and depth limits to avoid wasting too much searching large
pattern trees. Almost all matches are going to fail. */ pattern trees. Almost all matches are going to fail. */
if (match_data == NULL) if (match_data == NULL)
@ -168,7 +168,7 @@ for (i = 0; i < 2; i++)
return 0; return 0;
} }
(void)pcre2_set_match_limit(match_context, 100); (void)pcre2_set_match_limit(match_context, 100);
(void)pcre2_set_recursion_limit(match_context, 100); (void)pcre2_set_depth_limit(match_context, 100);
(void)pcre2_set_callout(match_context, callout_function, &callout_count); (void)pcre2_set_callout(match_context, callout_function, &callout_count);
} }

View File

@ -923,6 +923,7 @@ a positive value. */
#define STRING_NOTEMPTY_RIGHTPAR "NOTEMPTY)" #define STRING_NOTEMPTY_RIGHTPAR "NOTEMPTY)"
#define STRING_NOTEMPTY_ATSTART_RIGHTPAR "NOTEMPTY_ATSTART)" #define STRING_NOTEMPTY_ATSTART_RIGHTPAR "NOTEMPTY_ATSTART)"
#define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH=" #define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH="
#define STRING_LIMIT_DEPTH_EQ "LIMIT_DEPTH="
#define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION=" #define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION="
#define STRING_MARK "MARK" #define STRING_MARK "MARK"
@ -1196,6 +1197,7 @@ only. */
#define STRING_NOTEMPTY_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_RIGHT_PARENTHESIS #define STRING_NOTEMPTY_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_RIGHT_PARENTHESIS
#define STRING_NOTEMPTY_ATSTART_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_UNDERSCORE STR_A STR_T STR_S STR_T STR_A STR_R STR_T STR_RIGHT_PARENTHESIS #define STRING_NOTEMPTY_ATSTART_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_UNDERSCORE STR_A STR_T STR_S STR_T STR_A STR_R STR_T STR_RIGHT_PARENTHESIS
#define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN #define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN
#define STRING_LIMIT_DEPTH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_D STR_E STR_P STR_T STR_H STR_EQUALS_SIGN
#define STRING_LIMIT_RECURSION_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN #define STRING_LIMIT_RECURSION_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN
#define STRING_MARK STR_M STR_A STR_R STR_K #define STRING_MARK STR_M STR_A STR_R STR_K

View File

@ -586,7 +586,7 @@ typedef struct pcre2_real_match_context {
void *callout_data; void *callout_data;
PCRE2_SIZE offset_limit; PCRE2_SIZE offset_limit;
uint32_t match_limit; uint32_t match_limit;
uint32_t recursion_limit; uint32_t depth_limit;
} pcre2_real_match_context; } pcre2_real_match_context;
/* The real compiled code structure. The type for the blocksize field is /* The real compiled code structure. The type for the blocksize field is
@ -615,7 +615,7 @@ typedef struct pcre2_real_code {
uint32_t overall_options; /* Options after processing the pattern */ uint32_t overall_options; /* Options after processing the pattern */
uint32_t flags; /* Various state flags */ uint32_t flags; /* Various state flags */
uint32_t limit_match; /* Limit set in the pattern */ uint32_t limit_match; /* Limit set in the pattern */
uint32_t limit_recursion; /* Limit set in the pattern */ uint32_t limit_depth; /* Limit set in the pattern */
uint32_t first_codeunit; /* Starting code unit */ uint32_t first_codeunit; /* Starting code unit */
uint32_t last_codeunit; /* This codeunit must be seen */ uint32_t last_codeunit; /* This codeunit must be seen */
uint16_t bsr_convention; /* What \R matches */ uint16_t bsr_convention; /* What \R matches */
@ -810,7 +810,7 @@ typedef struct match_block {
heapframe *stack_frames; /* The original vector on the stack */ heapframe *stack_frames; /* The original vector on the stack */
uint32_t match_call_count; /* Number of times a new frame is created */ uint32_t match_call_count; /* Number of times a new frame is created */
uint32_t match_limit; /* As it says */ uint32_t match_limit; /* As it says */
uint32_t match_limit_recursion; /* As it says */ uint32_t match_limit_depth; /* As it says */
BOOL hitend; /* Hit the end of the subject at some point */ BOOL hitend; /* Hit the end of the subject at some point */
BOOL hasthen; /* Pattern contains (*THEN) */ BOOL hasthen; /* Pattern contains (*THEN) */
const uint8_t *lcc; /* Points to lower casing table */ const uint8_t *lcc; /* Points to lower casing table */
@ -856,7 +856,7 @@ typedef struct dfa_match_block {
PCRE2_SPTR last_used_ptr; /* Latest consulted character */ PCRE2_SPTR last_used_ptr; /* Latest consulted character */
const uint8_t *tables; /* Character tables */ const uint8_t *tables; /* Character tables */
PCRE2_SIZE start_offset; /* The start offset value */ PCRE2_SIZE start_offset; /* The start offset value */
uint32_t match_limit_recursion; /* As it says */ uint32_t match_limit_depth; /* As it says */
uint32_t moptions; /* Match options */ uint32_t moptions; /* Match options */
uint32_t poptions; /* Pattern options */ uint32_t poptions; /* Pattern options */
uint32_t nltype; /* Newline type */ uint32_t nltype; /* Newline type */

View File

@ -548,7 +548,7 @@ Returns: MATCH_MATCH if matched ) these values are >= 0
MATCH_NOMATCH if failed to match ) MATCH_NOMATCH if failed to match )
negative MATCH_xxx value for PRUNE, SKIP, etc negative MATCH_xxx value for PRUNE, SKIP, etc
negative PCRE2_ERROR_xxx value if aborted by an error condition negative PCRE2_ERROR_xxx value if aborted by an error condition
(e.g. stopped by repeated call or recursion limit) (e.g. stopped by repeated call or depth limit)
*/ */
static int static int
@ -708,7 +708,7 @@ recursive depth limit (used too many backtracking frames). If not, process the
opcodes. */ opcodes. */
if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT; if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT;
if (Frdepth >= mb->match_limit_recursion) return PCRE2_ERROR_RECURSIONLIMIT; if (Frdepth >= mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;
for (;;) for (;;)
{ {
@ -6272,9 +6272,9 @@ memset((char *)(mb->match_frames) + offsetof(heapframe, ovector), 0xff,
smaller. */ smaller. */
mb->match_limit = (mcontext->match_limit < re->limit_match)? mb->match_limit = (mcontext->match_limit < re->limit_match)?
mcontext->match_limit : re->limit_match; mcontext->match_limit : re->limit_match;
mb->match_limit_recursion = (mcontext->recursion_limit < re->limit_recursion)? mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)?
mcontext->recursion_limit : re->limit_recursion; mcontext->depth_limit : re->limit_depth;
/* Pointers to the individual character tables */ /* Pointers to the individual character tables */

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016 University of Cambridge New API code Copyright (c) 2016-2017 University of Cambridge
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -75,6 +75,7 @@ if (where == NULL) /* Requests field length */
case PCRE2_INFO_BACKREFMAX: case PCRE2_INFO_BACKREFMAX:
case PCRE2_INFO_BSR: case PCRE2_INFO_BSR:
case PCRE2_INFO_CAPTURECOUNT: case PCRE2_INFO_CAPTURECOUNT:
case PCRE2_INFO_DEPTHLIMIT:
case PCRE2_INFO_FIRSTCODETYPE: case PCRE2_INFO_FIRSTCODETYPE:
case PCRE2_INFO_FIRSTCODEUNIT: case PCRE2_INFO_FIRSTCODEUNIT:
case PCRE2_INFO_HASBACKSLASHC: case PCRE2_INFO_HASBACKSLASHC:
@ -89,7 +90,6 @@ if (where == NULL) /* Requests field length */
case PCRE2_INFO_NAMEENTRYSIZE: case PCRE2_INFO_NAMEENTRYSIZE:
case PCRE2_INFO_NAMECOUNT: case PCRE2_INFO_NAMECOUNT:
case PCRE2_INFO_NEWLINE: case PCRE2_INFO_NEWLINE:
case PCRE2_INFO_RECURSIONLIMIT:
return sizeof(uint32_t); return sizeof(uint32_t);
case PCRE2_INFO_FIRSTBITMAP: case PCRE2_INFO_FIRSTBITMAP:
@ -137,6 +137,11 @@ switch(what)
*((uint32_t *)where) = re->top_bracket; *((uint32_t *)where) = re->top_bracket;
break; break;
case PCRE2_INFO_DEPTHLIMIT:
*((uint32_t *)where) = re->limit_depth;
if (re->limit_depth == UINT32_MAX) return PCRE2_ERROR_UNSET;
break;
case PCRE2_INFO_FIRSTCODETYPE: case PCRE2_INFO_FIRSTCODETYPE:
*((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? 1 : *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? 1 :
((re->flags & PCRE2_STARTLINE) != 0)? 2 : 0; ((re->flags & PCRE2_STARTLINE) != 0)? 2 : 0;
@ -215,11 +220,6 @@ switch(what)
*((uint32_t *)where) = re->newline_convention; *((uint32_t *)where) = re->newline_convention;
break; break;
case PCRE2_INFO_RECURSIONLIMIT:
*((uint32_t *)where) = re->limit_recursion;
if (re->limit_recursion == UINT32_MAX) return PCRE2_ERROR_UNSET;
break;
case PCRE2_INFO_SIZE: case PCRE2_INFO_SIZE:
*((size_t *)where) = re->blocksize; *((size_t *)where) = re->blocksize;
break; break;

View File

@ -13,7 +13,7 @@ distribution because other apparatus is needed to compile pcre2grep for z/OS.
The header can be found in the special z/OS distribution, which is available The header can be found in the special z/OS distribution, which is available
from www.zaconsultants.net or from www.cbttape.org. from www.zaconsultants.net or from www.cbttape.org.
Copyright (c) 1997-2016 University of Cambridge Copyright (c) 1997-2017 University of Cambridge
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -211,7 +211,7 @@ static const uint8_t *character_tables = NULL;
static uint32_t pcre2_options = 0; static uint32_t pcre2_options = 0;
static uint32_t process_options = 0; static uint32_t process_options = 0;
static uint32_t match_limit = 0; static uint32_t match_limit = 0;
static uint32_t recursion_limit = 0; static uint32_t depth_limit = 0;
static pcre2_compile_context *compile_context; static pcre2_compile_context *compile_context;
static pcre2_match_context *match_context; static pcre2_match_context *match_context;
@ -355,7 +355,7 @@ used to identify them. */
#define N_FOFFSETS (-11) #define N_FOFFSETS (-11)
#define N_LBUFFER (-12) #define N_LBUFFER (-12)
#define N_M_LIMIT (-13) #define N_M_LIMIT (-13)
#define N_M_LIMIT_REC (-14) #define N_M_LIMIT_DEP (-14)
#define N_BUFSIZE (-15) #define N_BUFSIZE (-15)
#define N_NOJIT (-16) #define N_NOJIT (-16)
#define N_FILE_LIST (-17) #define N_FILE_LIST (-17)
@ -395,8 +395,9 @@ static option_item optionlist[] = {
{ OP_NODATA, N_LBUFFER, NULL, "line-buffered", "use line buffering" }, { OP_NODATA, N_LBUFFER, NULL, "line-buffered", "use line buffering" },
{ OP_NODATA, N_LOFFSETS, NULL, "line-offsets", "output line numbers and offsets, not text" }, { OP_NODATA, N_LOFFSETS, NULL, "line-offsets", "output line numbers and offsets, not text" },
{ OP_STRING, N_LOCALE, &locale, "locale=locale", "use the named locale" }, { OP_STRING, N_LOCALE, &locale, "locale=locale", "use the named locale" },
{ OP_U32NUMBER, N_M_LIMIT, &match_limit, "match-limit=number", "set PCRE match limit option" }, { OP_U32NUMBER, N_M_LIMIT, &match_limit, "match-limit=number", "set PCRE2 match limit option" },
{ OP_U32NUMBER, N_M_LIMIT_REC, &recursion_limit, "recursion-limit=number", "set PCRE match recursion limit option" }, { OP_U32NUMBER, N_M_LIMIT_DEP, &depth_limit, "depth-limit=number", "set PCRE2 depth limit option" },
{ OP_U32NUMBER, N_M_LIMIT_DEP, &depth_limit, "recursion-limit=number", "obsolete synonym for depth-limit" },
{ OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" }, { OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" },
{ OP_STRING, 'N', &newline_arg, "newline=type", "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" }, { OP_STRING, 'N', &newline_arg, "newline=type", "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" },
{ OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" }, { OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" },
@ -523,7 +524,7 @@ if (resource_error)
{ {
fprintf(stderr, "pcre2grep: Error %d, %d or %d means that a resource limit " fprintf(stderr, "pcre2grep: Error %d, %d or %d means that a resource limit "
"was exceeded.\n", PCRE2_ERROR_JIT_STACKLIMIT, PCRE2_ERROR_MATCHLIMIT, "was exceeded.\n", PCRE2_ERROR_JIT_STACKLIMIT, PCRE2_ERROR_MATCHLIMIT,
PCRE2_ERROR_RECURSIONLIMIT); PCRE2_ERROR_DEPTHLIMIT);
fprintf(stderr, "pcre2grep: Check your regex for nested unlimited loops.\n"); fprintf(stderr, "pcre2grep: Check your regex for nested unlimited loops.\n");
} }
exit(rc); exit(rc);
@ -1639,7 +1640,7 @@ for (i = 1; p != NULL; p = p->next, i++)
fprintf(stderr, "%s", msg); fprintf(stderr, "%s", msg);
FWRITE(matchptr, 1, slen, stderr); /* In case binary zero included */ FWRITE(matchptr, 1, slen, stderr); /* In case binary zero included */
fprintf(stderr, "\n\n"); fprintf(stderr, "\n\n");
if (*mrc == PCRE2_ERROR_MATCHLIMIT || *mrc == PCRE2_ERROR_RECURSIONLIMIT || if (*mrc == PCRE2_ERROR_MATCHLIMIT || *mrc == PCRE2_ERROR_DEPTHLIMIT ||
*mrc == PCRE2_ERROR_JIT_STACKLIMIT) *mrc == PCRE2_ERROR_JIT_STACKLIMIT)
resource_error = TRUE; resource_error = TRUE;
if (error_count++ > 20) if (error_count++ > 20)
@ -3530,7 +3531,7 @@ if ((only_matching != NULL && (file_offsets || line_offsets)) ||
/* Put limits into the match data block. */ /* Put limits into the match data block. */
if (match_limit > 0) pcre2_set_match_limit(match_context, match_limit); if (match_limit > 0) pcre2_set_match_limit(match_context, match_limit);
if (recursion_limit > 0) pcre2_set_recursion_limit(match_context, recursion_limit); if (depth_limit > 0) pcre2_set_depth_limit(match_context, depth_limit);
if (only_matching != NULL || file_offsets || line_offsets) if (only_matching != NULL || file_offsets || line_offsets)
show_only_matching = TRUE; show_only_matching = TRUE;

View File

@ -11,7 +11,7 @@ hacked-up (non-) design had also run out of steam.
Written by Philip Hazel Written by Philip Hazel
Original code Copyright (c) 1997-2012 University of Cambridge Original code Copyright (c) 1997-2012 University of Cambridge
Rewritten code Copyright (c) 2016 University of Cambridge Rewritten code Copyright (c) 2016-2017 University of Cambridge
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -564,6 +564,7 @@ static modstruct modlist[] = {
{ "caseless", MOD_PATP, MOD_OPT, PCRE2_CASELESS, PO(options) }, { "caseless", MOD_PATP, MOD_OPT, PCRE2_CASELESS, PO(options) },
{ "copy", MOD_DAT, MOD_NN, DO(copy_numbers), DO(copy_names) }, { "copy", MOD_DAT, MOD_NN, DO(copy_numbers), DO(copy_names) },
{ "debug", MOD_PAT, MOD_CTL, CTL_DEBUG, PO(control) }, { "debug", MOD_PAT, MOD_CTL, CTL_DEBUG, PO(control) },
{ "depth_limit", MOD_CTM, MOD_INT, 0, MO(depth_limit) },
{ "dfa", MOD_DAT, MOD_CTL, CTL_DFA, DO(control) }, { "dfa", MOD_DAT, MOD_CTL, CTL_DFA, DO(control) },
{ "dfa_restart", MOD_DAT, MOD_OPT, PCRE2_DFA_RESTART, DO(options) }, { "dfa_restart", MOD_DAT, MOD_OPT, PCRE2_DFA_RESTART, DO(options) },
{ "dfa_shortest", MOD_DAT, MOD_OPT, PCRE2_DFA_SHORTEST, DO(options) }, { "dfa_shortest", MOD_DAT, MOD_OPT, PCRE2_DFA_SHORTEST, DO(options) },
@ -619,7 +620,7 @@ static modstruct modlist[] = {
{ "push", MOD_PAT, MOD_CTL, CTL_PUSH, PO(control) }, { "push", MOD_PAT, MOD_CTL, CTL_PUSH, PO(control) },
{ "pushcopy", MOD_PAT, MOD_CTL, CTL_PUSHCOPY, PO(control) }, { "pushcopy", MOD_PAT, MOD_CTL, CTL_PUSHCOPY, PO(control) },
{ "pushtablescopy", MOD_PAT, MOD_CTL, CTL_PUSHTABLESCOPY, PO(control) }, { "pushtablescopy", MOD_PAT, MOD_CTL, CTL_PUSHTABLESCOPY, PO(control) },
{ "recursion_limit", MOD_CTM, MOD_INT, 0, MO(recursion_limit) }, { "recursion_limit", MOD_CTM, MOD_INT, 0, MO(depth_limit) }, /* Obsolete synonym */
{ "regerror_buffsize", MOD_PAT, MOD_INT, 0, PO(regerror_buffsize) }, { "regerror_buffsize", MOD_PAT, MOD_INT, 0, PO(regerror_buffsize) },
{ "replace", MOD_PND, MOD_STR, REPLACE_MODSIZE, PO(replacement) }, { "replace", MOD_PND, MOD_STR, REPLACE_MODSIZE, PO(replacement) },
{ "stackguard", MOD_PAT, MOD_INT, 0, PO(stackguard_test) }, { "stackguard", MOD_PAT, MOD_INT, 0, PO(stackguard_test) },
@ -1185,6 +1186,14 @@ are supported. */
else \ else \
pcre2_set_compile_recursion_guard_32(G(a,32),b,c) pcre2_set_compile_recursion_guard_32(G(a,32),b,c)
#define PCRE2_SET_DEPTH_LIMIT(a,b) \
if (test_mode == PCRE8_MODE) \
pcre2_set_depth_limit_8(G(a,8),b); \
else if (test_mode == PCRE16_MODE) \
pcre2_set_depth_limit_16(G(a,16),b); \
else \
pcre2_set_depth_limit_32(G(a,32),b)
#define PCRE2_SET_MATCH_LIMIT(a,b) \ #define PCRE2_SET_MATCH_LIMIT(a,b) \
if (test_mode == PCRE8_MODE) \ if (test_mode == PCRE8_MODE) \
pcre2_set_match_limit_8(G(a,8),b); \ pcre2_set_match_limit_8(G(a,8),b); \
@ -1217,14 +1226,6 @@ are supported. */
else \ else \
pcre2_set_parens_nest_limit_32(G(a,32),b) pcre2_set_parens_nest_limit_32(G(a,32),b)
#define PCRE2_SET_RECURSION_LIMIT(a,b) \
if (test_mode == PCRE8_MODE) \
pcre2_set_recursion_limit_8(G(a,8),b); \
else if (test_mode == PCRE16_MODE) \
pcre2_set_recursion_limit_16(G(a,16),b); \
else \
pcre2_set_recursion_limit_32(G(a,32),b)
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
if (test_mode == PCRE8_MODE) \ if (test_mode == PCRE8_MODE) \
a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \ a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \
@ -1620,6 +1621,12 @@ the three different cases. */
else \ else \
G(pcre2_set_compile_recursion_guard_,BITTWO)(G(a,BITTWO),b,c) G(pcre2_set_compile_recursion_guard_,BITTWO)(G(a,BITTWO),b,c)
#define PCRE2_SET_DEPTH_LIMIT(a,b) \
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
G(pcre2_set_depth_limit_,BITONE)(G(a,BITONE),b); \
else \
G(pcre2_set_depth_limit_,BITTWO)(G(a,BITTWO),b)
#define PCRE2_SET_MATCH_LIMIT(a,b) \ #define PCRE2_SET_MATCH_LIMIT(a,b) \
if (test_mode == G(G(PCRE,BITONE),_MODE)) \ if (test_mode == G(G(PCRE,BITONE),_MODE)) \
G(pcre2_set_match_limit_,BITONE)(G(a,BITONE),b); \ G(pcre2_set_match_limit_,BITONE)(G(a,BITONE),b); \
@ -1644,12 +1651,6 @@ the three different cases. */
else \ else \
G(pcre2_set_parens_nest_limit_,BITTWO)(G(a,BITTWO),b) G(pcre2_set_parens_nest_limit_,BITTWO)(G(a,BITTWO),b)
#define PCRE2_SET_RECURSION_LIMIT(a,b) \
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
G(pcre2_set_recursion_limit_,BITONE)(G(a,BITONE),b); \
else \
G(pcre2_set_recursion_limit_,BITTWO)(G(a,BITTWO),b)
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
if (test_mode == G(G(PCRE,BITONE),_MODE)) \ if (test_mode == G(G(PCRE,BITONE),_MODE)) \
a = G(pcre2_substitute_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \ a = G(pcre2_substitute_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \
@ -1838,11 +1839,11 @@ the three different cases. */
#define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_8(G(a,8),b) #define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_8(G(a,8),b)
#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
pcre2_set_compile_recursion_guard_8(G(a,8),b,c) pcre2_set_compile_recursion_guard_8(G(a,8),b,c)
#define PCRE2_SET_DEPTH_LIMIT(a,b) pcre2_set_depth_limit_8(G(a,8),b)
#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_8(G(a,8),b) #define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_8(G(a,8),b)
#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_8(G(a,8),b) #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_8(G(a,8),b)
#define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_8(G(a,8),b) #define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_8(G(a,8),b)
#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_8(G(a,8),b) #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_8(G(a,8),b)
#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_8(G(a,8),b)
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \ a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \
(PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l) (PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l)
@ -1934,11 +1935,11 @@ the three different cases. */
#define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_16(G(a,16),b) #define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_16(G(a,16),b)
#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
pcre2_set_compile_recursion_guard_16(G(a,16),b,c) pcre2_set_compile_recursion_guard_16(G(a,16),b,c)
#define PCRE2_SET_DEPTH_LIMIT(a,b) pcre2_set_depth_limit_16(G(a,16),b)
#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_16(G(a,16),b) #define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_16(G(a,16),b)
#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_16(G(a,16),b) #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_16(G(a,16),b)
#define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_16(G(a,16),b) #define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_16(G(a,16),b)
#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_16(G(a,16),b) #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_16(G(a,16),b)
#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_16(G(a,16),b)
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \ a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \
(PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l) (PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l)
@ -2030,11 +2031,11 @@ the three different cases. */
#define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_32(G(a,32),b) #define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_32(G(a,32),b)
#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \ #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
pcre2_set_compile_recursion_guard_32(G(a,32),b,c) pcre2_set_compile_recursion_guard_32(G(a,32),b,c)
#define PCRE2_SET_DEPTH_LIMIT(a,b) pcre2_set_depth_limit_32(G(a,32),b)
#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_32(G(a,32),b) #define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_32(G(a,32),b)
#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_32(G(a,32),b) #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_32(G(a,32),b)
#define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_32(G(a,32),b) #define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_32(G(a,32),b)
#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_32(G(a,32),b) #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_32(G(a,32),b)
#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_32(G(a,32),b)
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \ #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \ a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \
(PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l) (PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)
@ -3937,11 +3938,11 @@ if ((pat_patctl.control & CTL_INFO) != 0)
{ {
void *nametable; void *nametable;
uint8_t *start_bits; uint8_t *start_bits;
BOOL match_limit_set, recursion_limit_set; BOOL match_limit_set, depth_limit_set;
uint32_t backrefmax, bsr_convention, capture_count, first_ctype, first_cunit, uint32_t backrefmax, bsr_convention, capture_count, first_ctype, first_cunit,
hasbackslashc, hascrorlf, jchanged, last_ctype, last_cunit, match_empty, hasbackslashc, hascrorlf, jchanged, last_ctype, last_cunit, match_empty,
match_limit, minlength, nameentrysize, namecount, newline_convention, match_limit, minlength, nameentrysize, namecount, newline_convention,
recursion_limit; depth_limit;
/* These info requests may return PCRE2_ERROR_UNSET. */ /* These info requests may return PCRE2_ERROR_UNSET. */
@ -3959,14 +3960,14 @@ if ((pat_patctl.control & CTL_INFO) != 0)
return PR_ABEND; return PR_ABEND;
} }
switch(pattern_info(PCRE2_INFO_RECURSIONLIMIT, &recursion_limit, TRUE)) switch(pattern_info(PCRE2_INFO_DEPTHLIMIT, &depth_limit, TRUE))
{ {
case 0: case 0:
recursion_limit_set = TRUE; depth_limit_set = TRUE;
break; break;
case PCRE2_ERROR_UNSET: case PCRE2_ERROR_UNSET:
recursion_limit_set = FALSE; depth_limit_set = FALSE;
break; break;
default: default:
@ -4006,8 +4007,8 @@ if ((pat_patctl.control & CTL_INFO) != 0)
if (match_limit_set) if (match_limit_set)
fprintf(outfile, "Match limit = %u\n", match_limit); fprintf(outfile, "Match limit = %u\n", match_limit);
if (recursion_limit_set) if (depth_limit_set)
fprintf(outfile, "Recursion limit = %u\n", recursion_limit); fprintf(outfile, "Depth limit = %u\n", depth_limit);
if (namecount > 0) if (namecount > 0)
{ {
@ -5228,7 +5229,7 @@ return PR_OK;
/************************************************* /*************************************************
* Check match or recursion limit * * Check match or depth limit *
*************************************************/ *************************************************/
static int static int
@ -5240,7 +5241,7 @@ uint32_t mid = 64;
uint32_t max = UINT32_MAX; uint32_t max = UINT32_MAX;
PCRE2_SET_MATCH_LIMIT(dat_context, max); PCRE2_SET_MATCH_LIMIT(dat_context, max);
PCRE2_SET_RECURSION_LIMIT(dat_context, max); PCRE2_SET_DEPTH_LIMIT(dat_context, max);
for (;;) for (;;)
{ {
@ -5250,7 +5251,7 @@ for (;;)
} }
else else
{ {
PCRE2_SET_RECURSION_LIMIT(dat_context, mid); PCRE2_SET_DEPTH_LIMIT(dat_context, mid);
} }
if ((pat_patctl.control & CTL_JITFAST) != 0) if ((pat_patctl.control & CTL_JITFAST) != 0)
@ -6547,15 +6548,15 @@ else for (gmatched = 0;; gmatched++)
(double)CLOCKS_PER_SEC); (double)CLOCKS_PER_SEC);
} }
/* Find the match and recursion limits if requested. The recursion limit /* Find the match and depth limits if requested. The depth limit
is not relevant for JIT. */ is not relevant for JIT. */
if ((dat_datctl.control & CTL_FINDLIMITS) != 0) if ((dat_datctl.control & CTL_FINDLIMITS) != 0)
{ {
capcount = check_match_limit(pp, ulen, PCRE2_ERROR_MATCHLIMIT, "match"); capcount = check_match_limit(pp, ulen, PCRE2_ERROR_MATCHLIMIT, "match");
if (FLD(compiled_code, executable_jit) == NULL) if (FLD(compiled_code, executable_jit) == NULL)
(void)check_match_limit(pp, ulen, PCRE2_ERROR_RECURSIONLIMIT, (void)check_match_limit(pp, ulen, PCRE2_ERROR_DEPTHLIMIT,
"recursion"); "depth");
} }
/* Otherwise just run a single match, setting up a callout if required (the /* Otherwise just run a single match, setting up a callout if required (the
@ -7285,8 +7286,8 @@ printf(" Internal link size = %d\n", optval);
printf(" Parentheses nest limit = %d\n", optval); printf(" Parentheses nest limit = %d\n", optval);
(void)PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, &optval); (void)PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, &optval);
printf(" Default match limit = %d\n", optval); printf(" Default match limit = %d\n", optval);
(void)PCRE2_CONFIG(PCRE2_CONFIG_RECURSIONLIMIT, &optval); (void)PCRE2_CONFIG(PCRE2_CONFIG_DEPTHLIMIT, &optval);
printf(" Default recursion depth limit = %d\n", optval); printf(" Default depth limit = %d\n", optval);
return 0; return 0;
} }

14
testdata/testinput15 vendored
View File

@ -43,14 +43,14 @@
/(*LIMIT_MATCH=4294967290)abc/ /(*LIMIT_MATCH=4294967290)abc/
/(*LIMIT_RECURSION=4294967280)abc/I /(*LIMIT_DEPTH=4294967280)abc/I
/(a+)*zz/ /(a+)*zz/
aaaaaaaaaaaaaz aaaaaaaaaaaaaz
aaaaaaaaaaaaaz\=match_limit=3000 aaaaaaaaaaaaaz\=match_limit=3000
/(a+)*zz/ /(a+)*zz/
aaaaaaaaaaaaaz\=recursion_limit=10 aaaaaaaaaaaaaz\=depth_limit=10
/(*LIMIT_MATCH=3000)(a+)*zz/I /(*LIMIT_MATCH=3000)(a+)*zz/I
aaaaaaaaaaaaaz aaaaaaaaaaaaaz
@ -63,16 +63,16 @@
aaaaaaaaaaaaaz aaaaaaaaaaaaaz
aaaaaaaaaaaaaz\=match_limit=3000 aaaaaaaaaaaaaz\=match_limit=3000
/(*LIMIT_RECURSION=10)(a+)*zz/I /(*LIMIT_DEPTH=10)(a+)*zz/I
aaaaaaaaaaaaaz aaaaaaaaaaaaaz
aaaaaaaaaaaaaz\=recursion_limit=1000 aaaaaaaaaaaaaz\=depth_limit=1000
/(*LIMIT_RECURSION=10)(*LIMIT_RECURSION=1000)(a+)*zz/I /(*LIMIT_DEPTH=10)(*LIMIT_DEPTH=1000)(a+)*zz/I
aaaaaaaaaaaaaz aaaaaaaaaaaaaz
/(*LIMIT_RECURSION=1000)(a+)*zz/I /(*LIMIT_DEPTH=1000)(a+)*zz/I
aaaaaaaaaaaaaz aaaaaaaaaaaaaz
aaaaaaaaaaaaaz\=recursion_limit=10 aaaaaaaaaaaaaz\=depth_limit=10
# These three have infinitely nested recursions. # These three have infinitely nested recursions.

4
testdata/testinput6 vendored
View File

@ -4882,8 +4882,8 @@
aaa\=allcaptures aaa\=allcaptures
a\=allcaptures a\=allcaptures
/(*LIMIT_RECURSION=100)^((.)(?1)|.)$/ /(*LIMIT_DEPTH=100)^((.)(?1)|.)$/
\= Expect recursion limit exceeded \= Expect depth limit exceeded
a[00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00] a[00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]
# End of testinput6 # End of testinput6

56
testdata/testoutput15 vendored
View File

@ -13,12 +13,12 @@ Last code unit = 'z'
Subject length lower bound = 2 Subject length lower bound = 2
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\=find_limits aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\=find_limits
Minimum match limit = 7 Minimum match limit = 7
Minimum recursion limit = 7 Minimum depth limit = 7
0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazz 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazz
1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaz\=find_limits aaaaaaaaaaaaaz\=find_limits
Minimum match limit = 20481 Minimum match limit = 20481
Minimum recursion limit = 30 Minimum depth limit = 30
No match No match
!((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)!I !((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)!I
@ -27,60 +27,60 @@ May match empty string
Subject length lower bound = 0 Subject length lower bound = 0
/* this is a C style comment */\=find_limits /* this is a C style comment */\=find_limits
Minimum match limit = 64 Minimum match limit = 64
Minimum recursion limit = 7 Minimum depth limit = 7
0: /* this is a C style comment */ 0: /* this is a C style comment */
1: /* this is a C style comment */ 1: /* this is a C style comment */
/^(?>a)++/ /^(?>a)++/
aa\=find_limits aa\=find_limits
Minimum match limit = 5 Minimum match limit = 5
Minimum recursion limit = 3 Minimum depth limit = 3
0: aa 0: aa
aaaaaaaaa\=find_limits aaaaaaaaa\=find_limits
Minimum match limit = 12 Minimum match limit = 12
Minimum recursion limit = 3 Minimum depth limit = 3
0: aaaaaaaaa 0: aaaaaaaaa
/(a)(?1)++/ /(a)(?1)++/
aa\=find_limits aa\=find_limits
Minimum match limit = 7 Minimum match limit = 7
Minimum recursion limit = 5 Minimum depth limit = 5
0: aa 0: aa
1: a 1: a
aaaaaaaaa\=find_limits aaaaaaaaa\=find_limits
Minimum match limit = 21 Minimum match limit = 21
Minimum recursion limit = 5 Minimum depth limit = 5
0: aaaaaaaaa 0: aaaaaaaaa
1: a 1: a
/a(?:.)*?a/ims /a(?:.)*?a/ims
abbbbbbbbbbbbbbbbbbbbba\=find_limits abbbbbbbbbbbbbbbbbbbbba\=find_limits
Minimum match limit = 24 Minimum match limit = 24
Minimum recursion limit = 3 Minimum depth limit = 3
0: abbbbbbbbbbbbbbbbbbbbba 0: abbbbbbbbbbbbbbbbbbbbba
/a(?:.(*THEN))*?a/ims /a(?:.(*THEN))*?a/ims
abbbbbbbbbbbbbbbbbbbbba\=find_limits abbbbbbbbbbbbbbbbbbbbba\=find_limits
Minimum match limit = 66 Minimum match limit = 66
Minimum recursion limit = 45 Minimum depth limit = 45
0: abbbbbbbbbbbbbbbbbbbbba 0: abbbbbbbbbbbbbbbbbbbbba
/a(?:.(*THEN:ABC))*?a/ims /a(?:.(*THEN:ABC))*?a/ims
abbbbbbbbbbbbbbbbbbbbba\=find_limits abbbbbbbbbbbbbbbbbbbbba\=find_limits
Minimum match limit = 66 Minimum match limit = 66
Minimum recursion limit = 45 Minimum depth limit = 45
0: abbbbbbbbbbbbbbbbbbbbba 0: abbbbbbbbbbbbbbbbbbbbba
/^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/ /^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/
aabbccddee\=find_limits aabbccddee\=find_limits
Minimum match limit = 7 Minimum match limit = 7
Minimum recursion limit = 7 Minimum depth limit = 7
0: aabbccddee 0: aabbccddee
/^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/ /^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/
aabbccddee\=find_limits aabbccddee\=find_limits
Minimum match limit = 12 Minimum match limit = 12
Minimum recursion limit = 12 Minimum depth limit = 12
0: aabbccddee 0: aabbccddee
1: aa 1: aa
2: bb 2: bb
@ -91,7 +91,7 @@ Minimum recursion limit = 12
/^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/ /^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/
aabbccddee\=find_limits aabbccddee\=find_limits
Minimum match limit = 10 Minimum match limit = 10
Minimum recursion limit = 10 Minimum depth limit = 10
0: aabbccddee 0: aabbccddee
1: aa 1: aa
2: cc 2: cc
@ -103,9 +103,9 @@ Failed: error 160 at offset 17: (*VERB) not recognized or malformed
/(*LIMIT_MATCH=4294967290)abc/ /(*LIMIT_MATCH=4294967290)abc/
Failed: error 160 at offset 24: (*VERB) not recognized or malformed Failed: error 160 at offset 24: (*VERB) not recognized or malformed
/(*LIMIT_RECURSION=4294967280)abc/I /(*LIMIT_DEPTH=4294967280)abc/I
Capturing subpattern count = 0 Capturing subpattern count = 0
Recursion limit = 4294967280 Depth limit = 4294967280
First code unit = 'a' First code unit = 'a'
Last code unit = 'c' Last code unit = 'c'
Subject length lower bound = 3 Subject length lower bound = 3
@ -117,8 +117,8 @@ No match
Failed: error -47: match limit exceeded Failed: error -47: match limit exceeded
/(a+)*zz/ /(a+)*zz/
aaaaaaaaaaaaaz\=recursion_limit=10 aaaaaaaaaaaaaz\=depth_limit=10
Failed: error -53: recursion limit exceeded Failed: error -53: matching depth limit exceeded
/(*LIMIT_MATCH=3000)(a+)*zz/I /(*LIMIT_MATCH=3000)(a+)*zz/I
Capturing subpattern count = 1 Capturing subpattern count = 1
@ -151,36 +151,36 @@ No match
aaaaaaaaaaaaaz\=match_limit=3000 aaaaaaaaaaaaaz\=match_limit=3000
Failed: error -47: match limit exceeded Failed: error -47: match limit exceeded
/(*LIMIT_RECURSION=10)(a+)*zz/I /(*LIMIT_DEPTH=10)(a+)*zz/I
Capturing subpattern count = 1 Capturing subpattern count = 1
Recursion limit = 10 Depth limit = 10
Starting code units: a z Starting code units: a z
Last code unit = 'z' Last code unit = 'z'
Subject length lower bound = 2 Subject length lower bound = 2
aaaaaaaaaaaaaz aaaaaaaaaaaaaz
Failed: error -53: recursion limit exceeded Failed: error -53: matching depth limit exceeded
aaaaaaaaaaaaaz\=recursion_limit=1000 aaaaaaaaaaaaaz\=depth_limit=1000
Failed: error -53: recursion limit exceeded Failed: error -53: matching depth limit exceeded
/(*LIMIT_RECURSION=10)(*LIMIT_RECURSION=1000)(a+)*zz/I /(*LIMIT_DEPTH=10)(*LIMIT_DEPTH=1000)(a+)*zz/I
Capturing subpattern count = 1 Capturing subpattern count = 1
Recursion limit = 1000 Depth limit = 1000
Starting code units: a z Starting code units: a z
Last code unit = 'z' Last code unit = 'z'
Subject length lower bound = 2 Subject length lower bound = 2
aaaaaaaaaaaaaz aaaaaaaaaaaaaz
No match No match
/(*LIMIT_RECURSION=1000)(a+)*zz/I /(*LIMIT_DEPTH=1000)(a+)*zz/I
Capturing subpattern count = 1 Capturing subpattern count = 1
Recursion limit = 1000 Depth limit = 1000
Starting code units: a z Starting code units: a z
Last code unit = 'z' Last code unit = 'z'
Subject length lower bound = 2 Subject length lower bound = 2
aaaaaaaaaaaaaz aaaaaaaaaaaaaz
No match No match
aaaaaaaaaaaaaz\=recursion_limit=10 aaaaaaaaaaaaaz\=depth_limit=10
Failed: error -53: recursion limit exceeded Failed: error -53: matching depth limit exceeded
# These three have infinitely nested recursions. # These three have infinitely nested recursions.

View File

@ -7680,9 +7680,9 @@ No match
** Ignored after DFA matching: allcaptures ** Ignored after DFA matching: allcaptures
0: a 0: a
/(*LIMIT_RECURSION=100)^((.)(?1)|.)$/ /(*LIMIT_DEPTH=100)^((.)(?1)|.)$/
\= Expect recursion limit exceeded \= Expect depth limit exceeded
a[00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00] a[00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]
Failed: error -53: recursion limit exceeded Failed: error -53: matching depth limit exceeded
# End of testinput6 # End of testinput6