Skip to content

Commit b37b07a

Browse files
committed
Fix leak in RE2::Set#add
See #104 When we raise an exception in re2_set_add, the memory used by the std::string used to store the error message is never freed so we need to free it ourselves manually. However, we also need a copy of what is inside it to return to the user so we turn that into a C string first. The maximum message size of 100 is taken from the length of the prefix of the message (33 characters) and the longest error message currently in RE2 (35 characters) plus a little extra in case new releases of RE2 add longer messages. Thanks to @peterzhu2118 for both authoring ruby_memcheck and helping find the source of these leaks.
1 parent 60e3d3f commit b37b07a

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

ext/re2/re2.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1589,7 +1589,13 @@ static VALUE re2_set_add(VALUE self, VALUE pattern) {
15891589

15901590
int index = s->set->Add(regex, &err);
15911591
if (index < 0) {
1592-
rb_raise(rb_eArgError, "str rejected by RE2::Set->Add(): %s", err.c_str());
1592+
char msg[100];
1593+
snprintf(msg, sizeof(msg), "str rejected by RE2::Set->Add(): %s",
1594+
err.c_str());
1595+
1596+
/* Manually destruct the error string before we throw an exception. */
1597+
err.~basic_string();
1598+
rb_raise(rb_eArgError, msg);
15931599
}
15941600

15951601
return INT2FIX(index);

0 commit comments

Comments
 (0)