[Pcre-svn] [346] code/trunk: A bug which was introduced by t…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [346] code/trunk: A bug which was introduced by the single character repetition optimization was fixed.
Revision: 346
          http://www.exim.org/viewvc/pcre2?view=rev&revision=346
Author:   zherczeg
Date:     2015-08-13 12:35:38 +0100 (Thu, 13 Aug 2015)
Log Message:
-----------
A bug which was introduced by the single character repetition optimization was fixed.


Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/src/pcre2_jit_compile.c
    code/trunk/src/pcre2_jit_test.c
    code/trunk/testdata/testoutput16


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2015-08-13 05:57:26 UTC (rev 345)
+++ code/trunk/ChangeLog    2015-08-13 11:35:38 UTC (rev 346)
@@ -139,7 +139,10 @@
 37. The JIT compiler should restore the control chain for empty possessive
 repeats. This issue was found by Karl Skomski with a custom LLVM fuzzer.


+38. A bug which was introduced by the single character repetition optimization
+was fixed.

+
Version 10.20 30-June-2015
--------------------------


Modified: code/trunk/src/pcre2_jit_compile.c
===================================================================
--- code/trunk/src/pcre2_jit_compile.c    2015-08-13 05:57:26 UTC (rev 345)
+++ code/trunk/src/pcre2_jit_compile.c    2015-08-13 11:35:38 UTC (rev 346)
@@ -400,6 +400,8 @@
   BOOL has_skip_arg;
   /* (*THEN) is found in the pattern. */
   BOOL has_then;
+  /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */
+  BOOL has_skip_in_assert_back;
   /* Currently in recurse or negative assert. */
   BOOL local_exit;
   /* Currently in a positive assert. */
@@ -818,6 +820,7 @@
 {
 int count;
 PCRE2_SPTR slot;
+PCRE2_SPTR assert_back_end = cc - 1;


 /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
 while (cc < ccend)
@@ -889,6 +892,13 @@
     cc += (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2*LINK_SIZE);
     break;


+    case OP_ASSERTBACK:
+    slot = bracketend(cc);
+    if (slot > assert_back_end)
+      assert_back_end = slot;
+    cc += 1 + LINK_SIZE;
+    break;
+
     case OP_THEN_ARG:
     common->has_then = TRUE;
     common->control_head_ptr = 1;
@@ -910,9 +920,17 @@
     cc += 1;
     break;


+    case OP_SKIP:
+    if (cc < assert_back_end)
+      common->has_skip_in_assert_back = TRUE;
+    cc += 1;
+    break;
+
     case OP_SKIP_ARG:
     common->control_head_ptr = 1;
     common->has_skip_arg = TRUE;
+    if (cc < assert_back_end)
+      common->has_skip_in_assert_back = TRUE;
     cc += 1 + 2 + cc[1];
     break;


@@ -1042,7 +1060,7 @@
return FALSE;
}

-static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start)
+static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_si depth)
{
PCRE2_SPTR next_alt;

@@ -1083,8 +1101,8 @@
       break;
       }


-    if (*cc == OP_BRA || *cc == OP_CBRA)
-      detect_fast_fail(common, cc, private_data_start);
+    if (depth > 0 && (*cc == OP_BRA || *cc == OP_CBRA))
+      detect_fast_fail(common, cc, private_data_start, depth - 1);


     if (is_accelerated_repeat(cc))
       {
@@ -2405,8 +2423,9 @@


SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr);

+OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw))
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0);
}

static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
@@ -8352,7 +8371,7 @@
}

if (fast_fail && fast_str_ptr != 0)
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), fast_str_ptr));
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), fast_str_ptr));

 /* Handle fixed part first. */
 if (exact > 1)
@@ -10518,8 +10537,8 @@
 set_private_data_ptrs(common, &private_data_size, ccend);
 if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
   {
-  if (!detect_fast_forward_skip(common, &private_data_size))
-    detect_fast_fail(common, common->start, &private_data_size);
+  if (!detect_fast_forward_skip(common, &private_data_size) && !common->has_skip_in_assert_back)
+    detect_fast_fail(common, common->start, &private_data_size, 4);
   }


SLJIT_ASSERT(common->fast_fail_start_ptr <= common->fast_fail_end_ptr);

Modified: code/trunk/src/pcre2_jit_test.c
===================================================================
--- code/trunk/src/pcre2_jit_test.c    2015-08-13 05:57:26 UTC (rev 345)
+++ code/trunk/src/pcre2_jit_test.c    2015-08-13 11:35:38 UTC (rev 346)
@@ -820,6 +820,7 @@
     { MU, A, 0, 0 | F_NOMATCH, "(?=a(*SKIP)b)ab|ad", "ad" },
     { MU, A, 0, 0, "(\\w+(*SKIP)#)", "abcd,xyz#," },
     { MU, A, 0, 0, "\\w+(*SKIP)#|mm", "abcd,xyz#," },
+    { MU, A, 0, 0 | F_NOMATCH, "b+(?<=(*SKIP)#c)|b+", "#bbb" },


     /* (*THEN) verb. */
     { MU, A, 0, 0, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcaabcaabcaabcnacm" },


Modified: code/trunk/testdata/testoutput16
===================================================================
--- code/trunk/testdata/testoutput16    2015-08-13 05:57:26 UTC (rev 345)
+++ code/trunk/testdata/testoutput16    2015-08-13 11:35:38 UTC (rev 346)
@@ -185,11 +185,11 @@
 Subject length lower bound = 2
 JIT compilation was successful
   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\=find_limits
-Minimum match limit = 3
+Minimum match limit = 2
  0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazz (JIT)
  1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaz\=find_limits
-Minimum match limit = 16384
+Minimum match limit = 16383
 No match (JIT)


 !((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)!I
@@ -198,25 +198,25 @@
 Subject length lower bound = 0
 JIT compilation was successful
    /* this is a C style comment */\=find_limits
-Minimum match limit = 2
+Minimum match limit = 1
  0: /* this is a C style comment */ (JIT)
  1: /* this is a C style comment */


 /^(?>a)++/
     aa\=find_limits
-Minimum match limit = 2
+Minimum match limit = 1
  0: aa (JIT)
     aaaaaaaaa\=find_limits
-Minimum match limit = 2
+Minimum match limit = 1
  0: aaaaaaaaa (JIT)


 /(a)(?1)++/
     aa\=find_limits
-Minimum match limit = 2
+Minimum match limit = 1
  0: aa (JIT)
  1: a
     aaaaaaaaa\=find_limits
-Minimum match limit = 2
+Minimum match limit = 1
  0: aaaaaaaaa (JIT)
  1: a


@@ -237,12 +237,12 @@

 /^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/
      aabbccddee\=find_limits
-Minimum match limit = 6
+Minimum match limit = 5
  0: aabbccddee (JIT)


 /^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/
      aabbccddee\=find_limits
-Minimum match limit = 6
+Minimum match limit = 5
  0: aabbccddee (JIT)
  1: aa
  2: bb
@@ -252,7 +252,7 @@


 /^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/
      aabbccddee\=find_limits
-Minimum match limit = 6
+Minimum match limit = 5
  0: aabbccddee (JIT)
  1: aa
  2: cc
@@ -260,7 +260,7 @@


 /^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/jitfast
      aabbccddee\=find_limits
-Minimum match limit = 6
+Minimum match limit = 5
  0: aabbccddee (JIT)
  1: aa
  2: cc