Skip to content

Commit de634de

Browse files
authored
Merge pull request #105 from mudge/plug-memory-leaks
Fix memory leaks found by ruby_memcheck
2 parents 23fab86 + befe65b commit de634de

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

Diff for: ext/re2/re2.cc

+33-3
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ static VALUE re2_scanner_rewind(VALUE self) {
227227
re2_scanner *c;
228228
Data_Get_Struct(self, re2_scanner, c);
229229

230+
delete c->input;
230231
c->input = new(std::nothrow) re2::StringPiece(StringValuePtr(c->text));
231232
c->eof = false;
232233

@@ -785,6 +786,10 @@ static VALUE re2_regexp_initialize(int argc, VALUE *argv, VALUE self) {
785786
re2_pattern *p;
786787

787788
rb_scan_args(argc, argv, "11", &pattern, &options);
789+
790+
/* Ensure pattern is a string. */
791+
StringValue(pattern);
792+
788793
Data_Get_Struct(self, re2_pattern, p);
789794

790795
if (RTEST(options)) {
@@ -1341,6 +1346,9 @@ static VALUE re2_regexp_match_p(const VALUE self, VALUE text) {
13411346
* c = RE2::Regexp.new('(\w+)').scan("Foo bar baz")
13421347
*/
13431348
static VALUE re2_regexp_scan(const VALUE self, VALUE text) {
1349+
/* Ensure text is a string. */
1350+
StringValue(text);
1351+
13441352
re2_pattern *p;
13451353
re2_scanner *c;
13461354

@@ -1382,6 +1390,9 @@ static VALUE re2_regexp_scan(const VALUE self, VALUE text) {
13821390
*/
13831391
static VALUE re2_Replace(VALUE, VALUE str, VALUE pattern,
13841392
VALUE rewrite) {
1393+
/* Ensure rewrite is a string. */
1394+
StringValue(rewrite);
1395+
13851396
re2_pattern *p;
13861397

13871398
/* Take a copy of str so it can be modified in-place by
@@ -1397,6 +1408,9 @@ static VALUE re2_Replace(VALUE, VALUE str, VALUE pattern,
13971408
return encoded_str_new(str_as_string.data(), str_as_string.size(),
13981409
p->pattern->options().encoding());
13991410
} else {
1411+
/* Ensure pattern is a string. */
1412+
StringValue(pattern);
1413+
14001414
RE2::Replace(&str_as_string, StringValuePtr(pattern),
14011415
StringValuePtr(rewrite));
14021416

@@ -1422,6 +1436,9 @@ static VALUE re2_Replace(VALUE, VALUE str, VALUE pattern,
14221436
*/
14231437
static VALUE re2_GlobalReplace(VALUE, VALUE str, VALUE pattern,
14241438
VALUE rewrite) {
1439+
/* Ensure rewrite is a string. */
1440+
StringValue(rewrite);
1441+
14251442
/* Take a copy of str so it can be modified in-place by
14261443
* RE2::GlobalReplace.
14271444
*/
@@ -1436,6 +1453,9 @@ static VALUE re2_GlobalReplace(VALUE, VALUE str, VALUE pattern,
14361453
return encoded_str_new(str_as_string.data(), str_as_string.size(),
14371454
p->pattern->options().encoding());
14381455
} else {
1456+
/* Ensure pattern is a string. */
1457+
StringValue(pattern);
1458+
14391459
RE2::GlobalReplace(&str_as_string, StringValuePtr(pattern),
14401460
StringValuePtr(rewrite));
14411461

@@ -1563,13 +1583,23 @@ static VALUE re2_set_initialize(int argc, VALUE *argv, VALUE self) {
15631583
static VALUE re2_set_add(VALUE self, VALUE pattern) {
15641584
StringValue(pattern);
15651585
re2::StringPiece regex(RSTRING_PTR(pattern), RSTRING_LEN(pattern));
1566-
std::string err;
15671586
re2_set *s;
15681587
Data_Get_Struct(self, re2_set, s);
15691588

1570-
int index = s->set->Add(regex, &err);
1589+
/* To prevent the memory of the err string leaking when we call rb_raise,
1590+
* take a copy of it and let it go out of scope.
1591+
*/
1592+
char msg[100];
1593+
int index;
1594+
1595+
{
1596+
std::string err;
1597+
index = s->set->Add(regex, &err);
1598+
strncpy(msg, err.c_str(), sizeof(msg));
1599+
}
1600+
15711601
if (index < 0) {
1572-
rb_raise(rb_eArgError, "str rejected by RE2::Set->Add(): %s", err.c_str());
1602+
rb_raise(rb_eArgError, "str rejected by RE2::Set->Add(): %s", msg);
15731603
}
15741604

15751605
return INT2FIX(index);

0 commit comments

Comments
 (0)