* string.c (rb_str_modify_expand): fix memory leak.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@34492 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2012-02-08 13:30:04 +00:00
parent 9a57bc8f55
commit 4e39dc864c
4 changed files with 25 additions and 4 deletions

View file

@ -1,3 +1,7 @@
Wed Feb 8 22:29:59 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* string.c (rb_str_modify_expand): fix memory leak.
Wed Feb 8 10:58:45 2012 Nobuyoshi Nakada <nobu@ruby-lang.org> Wed Feb 8 10:58:45 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/readline/readline.c (readline_attempted_completion_function): * ext/readline/readline.c (readline_attempted_completion_function):

View file

@ -7,8 +7,16 @@ bug_str_modify(VALUE str)
return str; return str;
} }
VALUE
bug_str_modify_expand(VALUE str, VALUE expand)
{
rb_str_modify_expand(str, NUM2LONG(expand));
return str;
}
void void
Init_modify(VALUE klass) Init_modify(VALUE klass)
{ {
rb_define_method(klass, "modify!", bug_str_modify, 0); rb_define_method(klass, "modify!", bug_str_modify, 0);
rb_define_method(klass, "modify_expand!", bug_str_modify_expand, 1);
} }

View file

@ -691,6 +691,7 @@ long rb_str_sublen(VALUE, long);
VALUE rb_str_substr(VALUE, long, long); VALUE rb_str_substr(VALUE, long, long);
VALUE rb_str_subseq(VALUE, long, long); VALUE rb_str_subseq(VALUE, long, long);
void rb_str_modify(VALUE); void rb_str_modify(VALUE);
void rb_str_modify_expand(VALUE, long);
VALUE rb_str_freeze(VALUE); VALUE rb_str_freeze(VALUE);
void rb_str_set_len(VALUE, long); void rb_str_set_len(VALUE, long);
VALUE rb_str_resize(VALUE, long); VALUE rb_str_resize(VALUE, long);

View file

@ -1328,12 +1328,20 @@ rb_str_modify_expand(VALUE str, long expand)
if (expand < 0) { if (expand < 0) {
rb_raise(rb_eArgError, "negative expanding string size"); rb_raise(rb_eArgError, "negative expanding string size");
} }
if (!str_independent(str) || if (!str_independent(str)) {
(expand > 0 &&
(!STR_EMBED_P(str) ||
RSTRING_LEN(str) + expand > RSTRING_EMBED_LEN_MAX))) {
str_make_independent_expand(str, expand); str_make_independent_expand(str, expand);
} }
else if (expand > 0) {
long len = RSTRING_LEN(str);
long capa = len + expand;
if (!STR_EMBED_P(str)) {
REALLOC_N(RSTRING(str)->as.heap.ptr, char, capa+1);
RSTRING(str)->as.heap.aux.capa = capa;
}
else if (capa > RSTRING_EMBED_LEN_MAX) {
str_make_independent_expand(str, expand);
}
}
ENC_CODERANGE_CLEAR(str); ENC_CODERANGE_CLEAR(str);
} }