зеркало из https://github.com/github/ruby.git
Fix memory leak in String#tr and String#tr_s
rb_enc_codepoint_len could raise, which would cause the memory in buf to leak. For example: str1 = "\xE0\xA0\xA1#{" " * 100}".force_encoding("EUC-JP") str2 = "" str3 = "a".force_encoding("Windows-31J") 10.times do 1_000_000.times do str1.tr_s(str2, str3) rescue end puts `ps -o rss= -p #{$$}` end Before: 17536 22752 28032 33312 38688 43968 49200 54432 59744 64992 After: 12176 12352 12352 12448 12448 12448 12448 12448 12448 12448
This commit is contained in:
Родитель
67a545b3d2
Коммит
e17c83e02c
19
string.c
19
string.c
|
@ -7987,7 +7987,14 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag)
|
|||
while (s < send) {
|
||||
int may_modify = 0;
|
||||
|
||||
c0 = c = rb_enc_codepoint_len((char *)s, (char *)send, &clen, e1);
|
||||
int r = rb_enc_precise_mbclen((char *)s, (char *)send, e1);
|
||||
if (!MBCLEN_CHARFOUND_P(r)) {
|
||||
xfree(buf);
|
||||
rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(e1));
|
||||
}
|
||||
clen = MBCLEN_CHARFOUND_LEN(r);
|
||||
c0 = c = rb_enc_mbc_to_codepoint((char *)s, (char *)send, e1);
|
||||
|
||||
tlen = enc == e1 ? clen : rb_enc_codelen(c, enc);
|
||||
|
||||
s += clen;
|
||||
|
@ -8067,7 +8074,15 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag)
|
|||
|
||||
while (s < send) {
|
||||
int may_modify = 0;
|
||||
c0 = c = rb_enc_codepoint_len((char *)s, (char *)send, &clen, e1);
|
||||
|
||||
int r = rb_enc_precise_mbclen((char *)s, (char *)send, e1);
|
||||
if (!MBCLEN_CHARFOUND_P(r)) {
|
||||
xfree(buf);
|
||||
rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(e1));
|
||||
}
|
||||
clen = MBCLEN_CHARFOUND_LEN(r);
|
||||
c0 = c = rb_enc_mbc_to_codepoint((char *)s, (char *)send, e1);
|
||||
|
||||
tlen = enc == e1 ? clen : rb_enc_codelen(c, enc);
|
||||
|
||||
if (c < 256) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче