diff options
author | David Mitchell <davem@iabyn.com> | 2014-12-20 15:30:01 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2014-12-31 11:28:51 +0000 |
commit | 382a7a77501a1e25895d78eca9cb6838c6d7e6a3 (patch) | |
tree | bbba5bf8de7dd79c688a4fd7bde16626c9e4d81e /regcomp.c | |
parent | 75763b3aeee4912655f280922a10857e88d74104 (diff) | |
download | perl-382a7a77501a1e25895d78eca9cb6838c6d7e6a3.tar.gz |
fix integer overflow in S_study_chunk().
It was calculating final_minlen + delta even when delta was already
SSize_t_MAX and final_minlen > 0.
This triggered it: /a(??{}){2}/.
Found by -fsanitize=undefined:
regcomp.c:5623:89: runtime error: signed integer overflow: 1 + 9223372036854775807 cannot be represented in type 'long'
Diffstat (limited to 'regcomp.c')
-rw-r--r-- | regcomp.c | 7 |
1 files changed, 5 insertions, 2 deletions
@@ -5647,8 +5647,11 @@ PerlIO_printf(Perl_debug_log, "LHS=%"UVuf" RHS=%"UVuf"\n", { SSize_t final_minlen= min < stopmin ? min : stopmin; - if (!(RExC_seen & REG_UNBOUNDED_QUANTIFIER_SEEN) && (RExC_maxlen < final_minlen + delta)) { - RExC_maxlen = final_minlen + delta; + if (!(RExC_seen & REG_UNBOUNDED_QUANTIFIER_SEEN)) { + if (final_minlen > SSize_t_MAX - delta) + RExC_maxlen = SSize_t_MAX; + else if (RExC_maxlen < final_minlen + delta) + RExC_maxlen = final_minlen + delta; } return final_minlen; } |