ruby-changes:29878
From: nobu <ko1@a...>
Date: Fri, 12 Jul 2013 16:28:54 +0900 (JST)
Subject: [ruby-changes:29878] nobu:r41930 (trunk): encoding.c: refill terminator at associating encoding
nobu 2013-07-12 16:28:40 +0900 (Fri, 12 Jul 2013) New Revision: 41930 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41930 Log: encoding.c: refill terminator at associating encoding * encoding.c (rb_enc_associate_index): refill the terminator if it becomes longer than before. [ruby-dev:47500] [Bug #8624] * string.c (str_null_char, str_fill_term): get rid of out of bound access. * string.c (rb_str_fill_terminator): add a parameter for the length of new terminator. Modified files: trunk/ChangeLog trunk/encoding.c trunk/internal.h trunk/string.c trunk/transcode.c Index: encoding.c =================================================================== --- encoding.c (revision 41929) +++ encoding.c (revision 41930) @@ -777,10 +777,12 @@ VALUE https://github.com/ruby/ruby/blob/trunk/encoding.c#L777 rb_enc_associate_index(VALUE obj, int idx) { rb_encoding *enc; + int oldidx, oldtermlen, termlen; /* enc_check_capable(obj);*/ rb_check_frozen(obj); - if (rb_enc_get_index(obj) == idx) + oldidx = rb_enc_get_index(obj); + if (oldidx == idx) return obj; if (SPECIAL_CONST_P(obj)) { rb_raise(rb_eArgError, "cannot set encoding"); @@ -790,6 +792,11 @@ rb_enc_associate_index(VALUE obj, int id https://github.com/ruby/ruby/blob/trunk/encoding.c#L792 !rb_enc_asciicompat(enc)) { ENC_CODERANGE_CLEAR(obj); } + termlen = rb_enc_mbminlen(enc); + oldtermlen = rb_enc_mbminlen(rb_enc_from_index(oldidx)); + if (oldtermlen < termlen && RB_TYPE_P(obj, T_STRING)) { + rb_str_fill_terminator(obj, oldtermlen); + } enc_set_index(obj, idx); return obj; } Index: ChangeLog =================================================================== --- ChangeLog (revision 41929) +++ ChangeLog (revision 41930) @@ -1,3 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Jul 12 16:28:37 2013 Nobuyoshi Nakada <nobu@r...> + + * encoding.c (rb_enc_associate_index): refill the terminator if it + becomes longer than before. [ruby-dev:47500] [Bug #8624] + + * string.c (str_null_char, str_fill_term): get rid of out of bound + access. + + * string.c (rb_str_fill_terminator): add a parameter for the length of + new terminator. + Fri Jul 12 11:26:25 2013 Masaki Matsushita <glass.saga@g...> * hash.c (rb_hash_reject_bang): do not call rb_hash_foreach() if RHash Index: string.c =================================================================== --- string.c (revision 41929) +++ string.c (revision 41930) @@ -1483,12 +1483,12 @@ rb_string_value_ptr(volatile VALUE *ptr) https://github.com/ruby/ruby/blob/trunk/string.c#L1483 } static const char * -str_null_char(const char *s, long len, rb_encoding *enc) +str_null_char(const char *s, long len, const int minlen, rb_encoding *enc) { int n; const char *e = s + len; - for (; s < e; s += n) { + for (; s + minlen <= e; s += n) { if (!rb_enc_codepoint_len(s, e, &n, enc)) return s; } return 0; @@ -1497,7 +1497,8 @@ str_null_char(const char *s, long len, r https://github.com/ruby/ruby/blob/trunk/string.c#L1497 static char * str_fill_term(VALUE str, char *s, long len, int termlen, rb_encoding *enc) { - long capa = rb_str_capacity(str) + 1; + int oldtermlen = rb_enc_mbminlen(enc); + long capa = rb_str_capacity(str) + oldtermlen; int n; if (capa < len + termlen) { @@ -1505,8 +1506,13 @@ str_fill_term(VALUE str, char *s, long l https://github.com/ruby/ruby/blob/trunk/string.c#L1506 } else { const char *e = s + len; - if (!rb_enc_ascget(e, e + termlen, &n, enc)) return s; - rb_str_modify(str); + int diff = 0; + if (termlen > oldtermlen) diff = termlen - oldtermlen; + if (!diff && str_independent(str) && + !rb_enc_ascget(e, e + oldtermlen, &n, enc)) { + return s; + } + str_make_independent_expand(str, diff); } s = RSTRING_PTR(str); TERM_FILL(s + len, termlen); @@ -1523,7 +1529,7 @@ rb_string_value_cstr(volatile VALUE *ptr https://github.com/ruby/ruby/blob/trunk/string.c#L1529 const int minlen = rb_enc_mbminlen(enc); if (minlen > 1) { - if (str_null_char(s, len, enc)) { + if (str_null_char(s, len, minlen, enc)) { rb_raise(rb_eArgError, "string contains null char"); } return str_fill_term(str, s, len, minlen, enc); @@ -1540,13 +1546,12 @@ rb_string_value_cstr(volatile VALUE *ptr https://github.com/ruby/ruby/blob/trunk/string.c#L1546 } void -rb_str_fill_terminator(VALUE str) +rb_str_fill_terminator(VALUE str, const int newminlen) { char *s = RSTRING_PTR(str); long len = RSTRING_LEN(str); rb_encoding *enc = rb_enc_get(str); - const int minlen = rb_enc_mbminlen(enc); - str_fill_term(str, s, len, minlen, enc); + str_fill_term(str, s, len, newminlen, enc); } VALUE Index: internal.h =================================================================== --- internal.h (revision 41929) +++ internal.h (revision 41930) @@ -441,7 +441,7 @@ VALUE rb_str_quote_unprintable(VALUE); https://github.com/ruby/ruby/blob/trunk/internal.h#L441 VALUE rb_id_quote_unprintable(ID); #define QUOTE(str) rb_str_quote_unprintable(str) #define QUOTE_ID(id) rb_id_quote_unprintable(id) -void rb_str_fill_terminator(VALUE str); +void rb_str_fill_terminator(VALUE str, const int termlen); /* struct.c */ VALUE rb_struct_init_copy(VALUE copy, VALUE s); Index: transcode.c =================================================================== --- transcode.c (revision 41929) +++ transcode.c (revision 41930) @@ -2760,7 +2760,6 @@ str_encode_associate(VALUE str, int enci https://github.com/ruby/ruby/blob/trunk/transcode.c#L2760 int cr = 0; rb_enc_associate_index(str, encidx); - rb_str_fill_terminator(str); /* transcoded string never be broken. */ if (rb_enc_asciicompat(rb_enc_from_index(encidx))) { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/