diff --git a/re2/set.cc b/re2/set.cc index 3f2a1f07..f976759a 100644 --- a/re2/set.cc +++ b/re2/set.cc @@ -105,7 +105,6 @@ bool RE2::Set::Compile() { ABSL_LOG(DFATAL) << "RE2::Set::Compile() called more than once"; return false; } - compiled_ = true; size_ = static_cast(elem_.size()); // Sort the elements by their patterns. This is good enough for now @@ -118,8 +117,6 @@ bool RE2::Set::Compile() { PODArray sub(size_); for (int i = 0; i < size_; i++) sub[i] = elem_[i].second; - elem_.clear(); - elem_.shrink_to_fit(); Regexp::ParseFlags pf = static_cast( options_.ParseFlags()); @@ -127,7 +124,13 @@ bool RE2::Set::Compile() { prog_.reset(Prog::CompileSet(re, anchor_, options_.max_mem())); re->Decref(); - return prog_ != nullptr; + + compiled_ = prog_ != nullptr; + if (compiled_) { + elem_.clear(); + elem_.shrink_to_fit(); + } + return compiled_; } bool RE2::Set::Match(absl::string_view text, std::vector* v) const { diff --git a/re2/testing/set_test.cc b/re2/testing/set_test.cc index 3282c169..82c6be8b 100644 --- a/re2/testing/set_test.cc +++ b/re2/testing/set_test.cc @@ -232,4 +232,16 @@ TEST(Set, MoveSemantics) { ASSERT_EQ(s1.Match("abc bar2 xyz", NULL), false); } +TEST(Set, CompileFailureDoesNotCrash) { + RE2::Options opt; + opt.set_max_mem(1); + RE2::Set s(opt, RE2::UNANCHORED); + ASSERT_EQ(s.Add("a", NULL), 0); + ASSERT_EQ(s.Size(), 1); + ASSERT_FALSE(s.Compile()); + ASSERT_EQ(s.Size(), 1); + std::vector v; + ASSERT_FALSE(s.Match("a", &v)); +} + } // namespace re2