diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-08-12 02:35:50 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-08-12 02:35:50 +0000 |
commit | 9fbd5955c043489d98419d6c749657e7c6eee30c (patch) | |
tree | d1cc5d70fe91b61eb2a118ce34fd97e233a917cc | |
parent | f54265a8eb872dbccb6e071aa62c840adf39e0a2 (diff) |
merge revision(s) 55427: [Backport #12503]
* string.c (tr_trans): consider terminator length and fix heap
overflow. reported by Guido Vranken <guido AT guidovranken.nl>.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@55872 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | string.c | 18 | ||||
-rw-r--r-- | version.h | 6 |
3 files changed, 18 insertions, 11 deletions
@@ -1,3 +1,8 @@ +Fri Aug 12 11:21:24 2016 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * string.c (tr_trans): consider terminator length and fix heap + overflow. reported by Guido Vranken <guido AT guidovranken.nl>. + Tue Jul 12 00:17:36 2016 NAKAMURA Usaku <usa@ruby-lang.org> * tool/fake.rb: don't fake libdir. use libdirname instead. @@ -5576,6 +5576,7 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) char *s, *send; VALUE hash = 0; int singlebyte = single_byte_optimizable(str); + int termlen; int cr; #define CHECK_IF_ASCII(c) \ @@ -5657,11 +5658,12 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) cr = ENC_CODERANGE_7BIT; str_modify_keep_cr(str); s = RSTRING_PTR(str); send = RSTRING_END(str); + termlen = rb_enc_mbminlen(enc); if (sflag) { int clen, tlen; long offset, max = RSTRING_LEN(str); unsigned int save = -1; - char *buf = ALLOC_N(char, max), *t = buf; + char *buf = ALLOC_N(char, max + termlen), *t = buf; while (s < send) { int may_modify = 0; @@ -5702,7 +5704,7 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) while (t - buf + tlen >= max) { offset = t - buf; max *= 2; - REALLOC_N(buf, char, max); + REALLOC_N(buf, char, max + termlen); t = buf + offset; } rb_enc_mbcput(c, t, enc); @@ -5715,7 +5717,7 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) if (!STR_EMBED_P(str)) { ruby_sized_xfree(STR_HEAP_PTR(str), STR_HEAP_SIZE(str)); } - TERM_FILL(t, rb_enc_mbminlen(enc)); + TERM_FILL(t, termlen); RSTRING(str)->as.heap.ptr = buf; RSTRING(str)->as.heap.len = t - buf; STR_SET_NOEMBED(str); @@ -5740,9 +5742,9 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) } } else { - int clen, tlen, max = (int)(RSTRING_LEN(str) * 1.2); - long offset; - char *buf = ALLOC_N(char, max), *t = buf; + int clen, tlen; + long offset, max = (long)((send - s) * 1.2); + char *buf = ALLOC_N(char, max + termlen), *t = buf; while (s < send) { int may_modify = 0; @@ -5775,7 +5777,7 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) while (t - buf + tlen >= max) { offset = t - buf; max *= 2; - REALLOC_N(buf, char, max); + REALLOC_N(buf, char, max + termlen); t = buf + offset; } if (s != t) { @@ -5791,7 +5793,7 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) if (!STR_EMBED_P(str)) { ruby_sized_xfree(STR_HEAP_PTR(str), STR_HEAP_SIZE(str)); } - TERM_FILL(t, rb_enc_mbminlen(enc)); + TERM_FILL(t, termlen); RSTRING(str)->as.heap.ptr = buf; RSTRING(str)->as.heap.len = t - buf; STR_SET_NOEMBED(str); @@ -1,9 +1,9 @@ #define RUBY_VERSION "2.2.6" -#define RUBY_RELEASE_DATE "2016-07-12" -#define RUBY_PATCHLEVEL 344 +#define RUBY_RELEASE_DATE "2016-08-12" +#define RUBY_PATCHLEVEL 345 #define RUBY_RELEASE_YEAR 2016 -#define RUBY_RELEASE_MONTH 7 +#define RUBY_RELEASE_MONTH 8 #define RUBY_RELEASE_DAY 12 #include "ruby/version.h" |