ruby-changes:29915
From: nobu <ko1@a...>
Date: Mon, 15 Jul 2013 02:21:54 +0900 (JST)
Subject: [ruby-changes:29915] nobu:r41967 (trunk): string.c: consider old terminator
nobu 2013-07-15 02:21:41 +0900 (Mon, 15 Jul 2013) New Revision: 41967 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41967 Log: string.c: consider old terminator * string.c (str_fill_term): consider old terminator length, and should not use rb_enc_ascget since it depends on the current encoding which may not be compatible with the new terminator. [Bug #8634] Modified files: trunk/ChangeLog trunk/string.c Index: ChangeLog =================================================================== --- ChangeLog (revision 41966) +++ ChangeLog (revision 41967) @@ -1,4 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 -Mon Jul 15 02:21:33 2013 Nobuyoshi Nakada <nobu@r...> +Mon Jul 15 02:21:39 2013 Nobuyoshi Nakada <nobu@r...> + + * string.c (str_fill_term): consider old terminator length, and should + not use rb_enc_ascget since it depends on the current encoding which + may not be compatible with the new terminator. [Bug #8634] * encoding.c (enc_inspect): use PRIsVALUE to preserve the result encoding. Index: string.c =================================================================== --- string.c (revision 41966) +++ string.c (revision 41967) @@ -1482,6 +1482,15 @@ rb_string_value_ptr(volatile VALUE *ptr) https://github.com/ruby/ruby/blob/trunk/string.c#L1482 return RSTRING_PTR(str); } +static int +zero_filled(const char *s, int n) +{ + for (; n > 0; --n) { + if (*s++) return 0; + } + return 1; +} + static const char * str_null_char(const char *s, long len, const int minlen, rb_encoding *enc) { @@ -1489,30 +1498,22 @@ str_null_char(const char *s, long len, c https://github.com/ruby/ruby/blob/trunk/string.c#L1498 const char *e = s + len; for (; s + minlen <= e; s += n) { - if (!rb_enc_codepoint_len(s, e, &n, enc)) return s; + if (zero_filled(s, minlen)) return s; } return 0; } static char * -str_fill_term(VALUE str, char *s, long len, int termlen, rb_encoding *enc) +str_fill_term(VALUE str, char *s, long len, int oldtermlen, int termlen) { - int oldtermlen = rb_enc_mbminlen(enc); - long capa = rb_str_capacity(str) + oldtermlen; - int n; + long capa = rb_str_capacity(str) + 1; if (capa < len + termlen) { - rb_str_modify_expand(str, len + termlen - capa); + rb_str_modify_expand(str, termlen); } - else { - const char *e = s + len; - 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); + else if (!str_independent(str)) { + if (zero_filled(s + len, termlen)) return s; + str_make_independent(str); } s = RSTRING_PTR(str); TERM_FILL(s + len, termlen); @@ -1532,7 +1533,7 @@ rb_string_value_cstr(volatile VALUE *ptr https://github.com/ruby/ruby/blob/trunk/string.c#L1533 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); + return str_fill_term(str, s, len, minlen, minlen); } if (!s || memchr(s, 0, len)) { rb_raise(rb_eArgError, "string contains null byte"); @@ -1551,7 +1552,7 @@ rb_str_fill_terminator(VALUE str, const https://github.com/ruby/ruby/blob/trunk/string.c#L1552 char *s = RSTRING_PTR(str); long len = RSTRING_LEN(str); rb_encoding *enc = rb_enc_get(str); - str_fill_term(str, s, len, newminlen, enc); + str_fill_term(str, s, len, rb_enc_mbminlen(enc), newminlen); } VALUE -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/