summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2007-06-13 08:53:45 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2007-06-13 08:53:45 +0000
commitfb6cb91d5a1156bf15b5d3b83b2ac6a8f54c369f (patch)
tree203a35eb5e866541a010733ff6e0acfe12b09c4b
parentcc7768ebfd86be3e6126739dd2c66c76bc197ca1 (diff)
downloadpcre-fb6cb91d5a1156bf15b5d3b83b2ac6a8f54c369f.tar.gz
Apply C++ patch to fix a bad optimization.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@179 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--ChangeLog7
-rw-r--r--pcrecpp.cc26
-rw-r--r--pcrecpp_unittest.cc7
3 files changed, 16 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index d1052c5..ed0305b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -62,6 +62,13 @@ Version 7.2 05-June-07
10. Inserted some missing (unsigned int) casts to get rid of compiler warnings.
+11. Applied patch from Google to remove an optimization that didn't quite work.
+ The report of the bug said:
+
+ pcrecpp::RE("a*").FullMatch("aaa") matches, while
+ pcrecpp::RE("a*?").FullMatch("aaa") does not, and
+ pcrecpp::RE("a*?\\z").FullMatch("aaa") does again.
+
Version 7.1 24-Apr-07
---------------------
diff --git a/pcrecpp.cc b/pcrecpp.cc
index 3fb7411..ffb873f 100644
--- a/pcrecpp.cc
+++ b/pcrecpp.cc
@@ -77,25 +77,14 @@ void RE::Init(const string& pat, const RE_Options* options) {
re_partial_ = Compile(UNANCHORED);
if (re_partial_ != NULL) {
- // Check for complicated patterns. The following change is
- // conservative in that it may treat some "simple" patterns
- // as "complex" (e.g., if the vertical bar is in a character
- // class or is escaped). But it seems good enough.
- if (strchr(pat.c_str(), '|') == NULL) {
- // Simple pattern: we can use position-based checks to perform
- // fully anchored matches
- re_full_ = re_partial_;
- } else {
- // We need a special pattern for anchored matches
- re_full_ = Compile(ANCHOR_BOTH);
- }
+ re_full_ = Compile(ANCHOR_BOTH);
}
}
void RE::Cleanup() {
- if (re_full_ != NULL && re_full_ != re_partial_) (*pcre_free)(re_full_);
- if (re_partial_ != NULL) (*pcre_free)(re_partial_);
- if (error_ != &empty_string) delete error_;
+ if (re_full_ != NULL) (*pcre_free)(re_full_);
+ if (re_partial_ != NULL) (*pcre_free)(re_partial_);
+ if (error_ != &empty_string) delete error_;
}
@@ -507,13 +496,6 @@ int RE::TryMatch(const StringPiece& text,
rc = vecsize / 2;
}
- if ((anchor == ANCHOR_BOTH) && (re_full_ == re_partial_)) {
- // We need an extra check to make sure that the match extended
- // to the end of the input string
- assert(vec[0] == 0); // PCRE_ANCHORED forces starting match
- if (vec[1] != text.size()) return 0; // Did not get ending match
- }
-
return rc;
}
diff --git a/pcrecpp_unittest.cc b/pcrecpp_unittest.cc
index 858728c..bfe26e5 100644
--- a/pcrecpp_unittest.cc
+++ b/pcrecpp_unittest.cc
@@ -806,8 +806,11 @@ int main(int argc, char** argv) {
/***** FullMatch with no args *****/
CHECK(RE("h.*o").FullMatch("hello"));
- CHECK(!RE("h.*o").FullMatch("othello"));
- CHECK(!RE("h.*o").FullMatch("hello!"));
+ CHECK(!RE("h.*o").FullMatch("othello")); // Must be anchored at front
+ CHECK(!RE("h.*o").FullMatch("hello!")); // Must be anchored at end
+ CHECK(RE("a*").FullMatch("aaaa")); // Fullmatch with normal op
+ CHECK(RE("a*?").FullMatch("aaaa")); // Fullmatch with nongreedy op
+ CHECK(RE("a*?\\z").FullMatch("aaaa")); // Two unusual ops
/***** FullMatch with args *****/