diff options
author | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2012-02-15 09:50:53 +0000 |
---|---|---|
committer | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2012-02-15 09:50:53 +0000 |
commit | f9c61d27520deee9f2007e7aa58e87c0f162d697 (patch) | |
tree | 4147f8d22e9d3ccdd1bc728e6367e3419a414d00 /pcre_dfa_exec.c | |
parent | 87e4a4ffccc78b7e4cebc73265472eef97c3ada8 (diff) | |
download | pcre-f9c61d27520deee9f2007e7aa58e87c0f162d697.tar.gz |
Fix several partial matching bugs for backrefs, \R, \X, and CRLF line endings.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@916 2f5784b3-3f2a-0410-8824-cb99058d5e15
Diffstat (limited to 'pcre_dfa_exec.c')
-rw-r--r-- | pcre_dfa_exec.c | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/pcre_dfa_exec.c b/pcre_dfa_exec.c index 21d7be6..cdda39d 100644 --- a/pcre_dfa_exec.c +++ b/pcre_dfa_exec.c @@ -424,6 +424,8 @@ BOOL utf = (md->poptions & PCRE_UTF8) != 0; BOOL utf = FALSE; #endif +BOOL reset_could_continue = FALSE; + rlevel++; offsetcount &= (-2); @@ -571,8 +573,10 @@ for (;;) int clen, dlen; unsigned int c, d; int forced_fail = 0; - BOOL could_continue = FALSE; - + BOOL partial_newline = FALSE; + BOOL could_continue = reset_could_continue; + reset_could_continue = FALSE; + /* Make the new state list into the active state list and empty the new state list. */ @@ -641,7 +645,8 @@ for (;;) /* A negative offset is a special case meaning "hold off going to this (negated) state until the number of characters in the data field have - been skipped". */ + been skipped". If the could_continue flag was passed over from a previous + state, arrange for it to passed on. */ if (state_offset < 0) { @@ -650,6 +655,7 @@ for (;;) DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP)); ADD_NEW_DATA(state_offset, current_state->count, current_state->data - 1); + if (could_continue) reset_could_continue = TRUE; continue; } else @@ -916,6 +922,19 @@ for (;;) (ptr == end_subject - md->nllen) )) { ADD_ACTIVE(state_offset + 1, 0); } + else if (ptr + 1 >= md->end_subject && + (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + if ((md->moptions & PCRE_PARTIAL_HARD) != 0) + { + reset_could_continue = TRUE; + ADD_NEW_DATA(-(state_offset + 1), 0, 1); + } + else could_continue = partial_newline = TRUE; + } } break; @@ -928,6 +947,19 @@ for (;;) else if (clen == 0 || ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr))) { ADD_ACTIVE(state_offset + 1, 0); } + else if (ptr + 1 >= md->end_subject && + (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + if ((md->moptions & PCRE_PARTIAL_HARD) != 0) + { + reset_could_continue = TRUE; + ADD_NEW_DATA(-(state_offset + 1), 0, 1); + } + else could_continue = partial_newline = TRUE; + } } else if (IS_NEWLINE(ptr)) { ADD_ACTIVE(state_offset + 1, 0); } @@ -1824,6 +1856,8 @@ for (;;) ncount++; nptr += ndlen; } + if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; if (++count >= GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } else @@ -2037,6 +2071,8 @@ for (;;) ncount++; nptr += nclen; } + if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; ADD_NEW_DATA(-(state_offset + 1), 0, ncount); } break; @@ -2062,14 +2098,20 @@ for (;;) break; case 0x000d: - if (ptr + 1 < end_subject && ptr[1] == 0x0a) + if (ptr + 1 >= end_subject) + { + ADD_NEW(state_offset + 1, 0); + if ((md->moptions & PCRE_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; + } + else if (ptr[1] == 0x0a) { ADD_NEW_DATA(-(state_offset + 1), 0, 1); } else - { + { ADD_NEW(state_offset + 1, 0); - } + } break; } break; @@ -2942,7 +2984,7 @@ for (;;) The "could_continue" variable is true if a state could have continued but for the fact that the end of the subject was reached. */ - + if (new_count <= 0) { if (rlevel == 1 && /* Top level, and */ @@ -2954,7 +2996,10 @@ for (;;) ((md->moptions & PCRE_PARTIAL_SOFT) != 0 && /* Soft partial and */ match_count < 0) /* no matches */ ) && /* And... */ - ptr >= end_subject && /* Reached end of subject */ + ( + ptr >= end_subject || /* Reached end of subject or */ + partial_newline /* a partial newline */ + ) && ptr > md->start_used_ptr) /* Inspected non-empty string */ { if (offsetcount >= 2) |