]> granicus.if.org Git - python/commitdiff
Backport r59862 (issue #712900): make long regexp matches interruptable
authorGuido van Rossum <guido@python.org>
Mon, 4 Feb 2008 22:00:35 +0000 (22:00 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 4 Feb 2008 22:00:35 +0000 (22:00 +0000)
by signals.

Misc/NEWS
Modules/_sre.c

index 5f28bd3b0521c06e8273b8d4b9487e4ca699f8e7..5cd8e4ab7e6684c1276170cbebdb063c0cc8923d 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -212,6 +212,8 @@ Library
 Extension Modules
 -----------------
 
+- Backport r59862 (issue #712900): make long regexp matches interruptable.
+
 - #1940: make it possible to use curses.filter() before curses.initscr()
   as the documentation says.
 
index 354210064bff49e7f14db71526696c432126b7e5..eb071ef591088719a593c31c2a7a04446b2b30d0 100644 (file)
@@ -99,6 +99,7 @@ static char copyright[] =
 #define SRE_ERROR_STATE -2 /* illegal state */
 #define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */
 #define SRE_ERROR_MEMORY -9 /* out of memory */
+#define SRE_ERROR_INTERRUPTED -10 /* signal handler raised exception */
 
 #if defined(VERBOSE)
 #define TRACE(v) printf v
@@ -809,6 +810,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
     Py_ssize_t alloc_pos, ctx_pos = -1;
     Py_ssize_t i, ret = 0;
     Py_ssize_t jump;
+    unsigned int sigcount=0;
 
     SRE_MATCH_CONTEXT* ctx;
     SRE_MATCH_CONTEXT* nextctx;
@@ -837,6 +839,9 @@ entrance:
     }
 
     for (;;) {
+        ++sigcount;
+        if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals())
+            RETURN_ERROR(SRE_ERROR_INTERRUPTED);
 
         switch (*ctx->pattern++) {
 
@@ -1834,6 +1839,9 @@ pattern_error(int status)
     case SRE_ERROR_MEMORY:
         PyErr_NoMemory();
         break;
+    case SRE_ERROR_INTERRUPTED:
+    /* An exception has already been raised, so let it fly */
+        break;
     default:
         /* other error codes indicate compiler/engine bugs */
         PyErr_SetString(