diff options
author | David Mitchell <davem@iabyn.com> | 2017-06-16 15:46:19 +0100 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2017-08-23 21:21:10 +0100 |
commit | d268074d893d83bd5bd8f0483bcc7c793bf84bdc (patch) | |
tree | 8e4e0e4983498f008bb723f5be9addd73fbc6912 /regexec.c | |
parent | 6aaabe5196719b29658e550df4d13c7984a10408 (diff) | |
download | perl-d268074d893d83bd5bd8f0483bcc7c793bf84bdc.tar.gz |
don't call Perl_fbm_instr() with negative length
RT #131575
re_intuit_start() could calculate a maximum end position less than the
current start position. This used to get rejected by fbm_intr(), until
v5.23.3-110-g147f21b, which made fbm_intr() faster and removed unnecessary
checks.
This commits fixes re_intuit_start(), and adds an assert to fbm_intr().
(cherry picked from commit bb152a4b442f7718fd37d32cc558be675e8ae1ae)
Diffstat (limited to 'regexec.c')
-rw-r--r-- | regexec.c | 17 |
1 files changed, 11 insertions, 6 deletions
@@ -126,13 +126,16 @@ static const char* const non_utf8_target_but_utf8_required (U8*)(off >= 0 ? reginfo->strend : reginfo->strbeg)) \ : (U8*)(pos + off)) -#define HOPBACKc(pos, off) \ - (char*)(reginfo->is_utf8_target \ - ? reghopmaybe3((U8*)pos, (SSize_t)0-off, (U8*)(reginfo->strbeg)) \ - : (pos - off >= reginfo->strbeg) \ - ? (U8*)pos - off \ +/* like HOPMAYBE3 but backwards. lim must be +ve. Returns NULL on overshoot */ +#define HOPBACK3(pos, off, lim) \ + (reginfo->is_utf8_target \ + ? reghopmaybe3((U8*)pos, (SSize_t)0-off, (U8*)(lim)) \ + : (pos - off >= lim) \ + ? (U8*)pos - off \ : NULL) +#define HOPBACKc(pos, off) ((char*)HOPBACK3(pos, off, reginfo->strbeg)) + #define HOP3(pos,off,lim) (reginfo->is_utf8_target ? reghop3((U8*)(pos), off, (U8*)(lim)) : (U8*)(pos + off)) #define HOP3c(pos,off,lim) ((char*)HOP3(pos,off,lim)) @@ -884,7 +887,9 @@ Perl_re_intuit_start(pTHX_ (IV)prog->check_end_shift); }); - end_point = HOP3(strend, -end_shift, strbeg); + end_point = HOPBACK3(strend, end_shift, rx_origin); + if (!end_point) + goto fail_finish; start_point = HOPMAYBE3(rx_origin, start_shift, end_point); if (!start_point) goto fail_finish; |