[Pcre-svn] [894] code/trunk: Update pcre2demo to deal with v…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [894] code/trunk: Update pcre2demo to deal with various \K inside assertion anomalies.
Revision: 894
          http://www.exim.org/viewvc/pcre2?view=rev&revision=894
Author:   ph10
Date:     2017-12-23 17:15:51 +0000 (Sat, 23 Dec 2017)
Log Message:
-----------
Update pcre2demo to deal with various \K inside assertion anomalies.


Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/src/pcre2demo.c


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2017-12-22 15:56:27 UTC (rev 893)
+++ code/trunk/ChangeLog    2017-12-23 17:15:51 UTC (rev 894)
@@ -95,7 +95,12 @@
 if the callout_extra subject modifier is set. These bits are provided to help
 with tracking how a backtracking match is proceeding.


+23. Updated the pcre2demo.c demonstration program, which was missing the extra
+code for -g that handles the case when \K in an assertion causes the match to
+end at the original start point. Also arranged for it to detect when \K causes
+the end of a match to be before its start.

+
Version 10.30 14-August-2017
----------------------------


Modified: code/trunk/src/pcre2demo.c
===================================================================
--- code/trunk/src/pcre2demo.c    2017-12-22 15:56:27 UTC (rev 893)
+++ code/trunk/src/pcre2demo.c    2017-12-23 17:15:51 UTC (rev 894)
@@ -211,6 +211,21 @@
 if (rc == 0)
   printf("ovector was not big enough for all the captured substrings\n");


+/* We must guard against patterns such as /(?=.\K)/ that use \K in an assertion
+to set the start of a match later than its end. In this demonstration program,
+we just detect this case and give up. */
+
+if (ovector[0] > ovector[1])
+  {
+  printf("\\K was used in an assertion to set the match start after its end.\n"
+    "From end to start the match was: %.*s\n", (int)(ovector[0] - ovector[1]),
+      (char *)(subject + ovector[1]));
+  printf("Run abandoned\n");
+  pcre2_match_data_free(match_data);
+  pcre2_code_free(re);
+  return 1;
+  }
+
 /* Show substrings stored in the output vector by number. Obviously, in a real
 application you might want to do things other than print them. */


@@ -338,6 +353,29 @@
     options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
     }


+  /* If the previous match was not an empty string, there is one tricky case to
+  consider. If a pattern contains \K within a lookbehind assertion at the
+  start, the end of the matched string can be at the offset where the match
+  started. Without special action, this leads to a loop that keeps on matching
+  the same substring. We must detect this case and arrange to move the start on
+  by one character. The pcre2_get_startchar() function returns the starting
+  offset that was passed to pcre2_match(). */
+
+  else
+    {
+    PCRE2_SIZE startchar = pcre2_get_startchar(match_data);
+    if (start_offset <= startchar)
+      {
+      if (startchar >= subject_length) break;   /* Reached end of subject.   */
+      start_offset = startchar + 1;             /* Advance by one character. */
+      if (utf8)                                 /* If UTF-8, it may be more  */
+        {                                       /*   than one code unit.     */
+        for (; start_offset < subject_length; start_offset++)
+          if ((subject[start_offset] & 0xc0) != 0x80) break;
+        }
+      }
+    }
+
   /* Run the next matching operation */


   rc = pcre2_match(
@@ -402,6 +440,21 @@
   if (rc == 0)
     printf("ovector was not big enough for all the captured substrings\n");


+  /* We must guard against patterns such as /(?=.\K)/ that use \K in an
+  assertion to set the start of a match later than its end. In this
+  demonstration program, we just detect this case and give up. */
+
+  if (ovector[0] > ovector[1])
+    {
+    printf("\\K was used in an assertion to set the match start after its end.\n"
+      "From end to start the match was: %.*s\n", (int)(ovector[0] - ovector[1]),
+        (char *)(subject + ovector[1]));
+    printf("Run abandoned\n");
+    pcre2_match_data_free(match_data);
+    pcre2_code_free(re);
+    return 1;
+    }
+
   /* As before, show substrings stored in the output vector by number, and then
   also any named substrings. */