}
- /* if the regex is absolutely anchored to the start of the string,
- * then check_offset_max represents an upper bound on the string
- * where the substr could start */
+ /* If the regex is absolutely anchored to either the start of the
+ * string (BOL,SBOL) or to pos() (ANCH_GPOS), then
+ * check_offset_max represents an upper bound on the string where
+ * the substr could start. For the ANCH_GPOS case, we assume that
+ * the caller of intuit will have already set strpos to
+ * pos()-gofs, so in this case strpos + offset_max will still be
+ * an upper bound on the substr.
+ */
if (!ml_anch
&& prog->intflags & PREGf_ANCH
- && prog->check_offset_max != SSize_t_MAX
- && start_shift < prog->check_offset_max)
+ && !(prog->intflags & PREGf_IMPLICIT)
+ && prog->check_offset_max != SSize_t_MAX)
{
SSize_t len = SvCUR(check) - !!SvTAIL(check);
- end_point = HOP3lim(start_point,
- prog->check_offset_max - start_shift,
- end_point -len)
- + len;
+ const char * const anchor =
+ (prog->intflags & PREGf_ANCH_GPOS ? strpos : strbeg);
+
+ /* do a bytes rather than chars comparison. It's conservative;
+ * so it skips doing the HOP if the result can't possibly end
+ * up earlier than the old value of end_point.
+ */
+ if ((char*)end_point - anchor > prog->check_offset_max) {
+ end_point = HOP3lim((U8*)anchor,
+ prog->check_offset_max,
+ end_point -len)
+ + len;
+ }
}
DEBUG_OPTIMISE_MORE_r({
require './test.pl';
}
-plan tests => 719; # Update this when adding/deleting tests.
+plan tests => 721; # Update this when adding/deleting tests.
run_tests() unless caller;
ok($_ =~ /^abc\Gdef$/, $message);
pos = 3;
ok($_ =~ /c\Gd/, $message);
+ pos = 3;
+ ok($_ =~ /..\GX?def/, $message);
}
{
$s =~ /(?-m:^)abcX?fg/m for 1..100;
pass("BOL within //m mustn't skip absolute anchored check");
+ $s = "abcdefg" x 1_000_000;
+ $s =~ /^XX\d{1,10}cde/ for 1..100;
+ pass("abs anchored float string should fail quickly");
+
}
# These are based on looking at the code in regcomp.c