[前][次][番号順一覧][スレッド一覧]

ruby-changes:41650

From: naruse <ko1@a...>
Date: Wed, 3 Feb 2016 13:52:17 +0900 (JST)
Subject: [ruby-changes:41650] naruse:r53724 (trunk): * string.c (str_new_frozen): if the given string is embeddedable

naruse	2016-02-03 13:52:13 +0900 (Wed, 03 Feb 2016)

  New Revision: 53724

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53724

  Log:
    * string.c (str_new_frozen): if the given string is embeddedable
      but not embedded, embed a new copied string. [Bug #11946]

  Modified files:
    trunk/ChangeLog
    trunk/ext/-test-/string/cstr.c
    trunk/string.c
    trunk/test/-ext-/string/test_cstr.rb
Index: string.c
===================================================================
--- string.c	(revision 53723)
+++ string.c	(revision 53724)
@@ -1090,6 +1090,13 @@ str_new_frozen(VALUE klass, VALUE orig) https://github.com/ruby/ruby/blob/trunk/string.c#L1090
 		return shared;
 	    }
 	}
+	else if (RSTRING_LEN(orig)+TERM_LEN(orig) <= RSTRING_EMBED_LEN_MAX+1) {
+	    str = str_alloc(klass);
+	    STR_SET_EMBED(str);
+	    memcpy(RSTRING_PTR(str), RSTRING_PTR(orig), RSTRING_LEN(orig));
+	    STR_SET_EMBED_LEN(str, RSTRING_LEN(orig));
+	    TERM_FILL(RSTRING_END(str), TERM_LEN(orig));
+	}
 	else {
 	    str = str_alloc(klass);
 	    STR_SET_NOEMBED(str);
Index: test/-ext-/string/test_cstr.rb
===================================================================
--- test/-ext-/string/test_cstr.rb	(revision 53723)
+++ test/-ext-/string/test_cstr.rb	(revision 53724)
@@ -36,6 +36,12 @@ class Test_StringCStr < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/test/-ext-/string/test_cstr.rb#L36
     end
   end
 
+  def test_rb_str_new_frozen_embed
+    str = Bug::String.cstr_noembed("rbconfig.rb")
+    str = Bug::String.rb_str_new_frozen(str)
+    assert_equal true, Bug::String.cstr_embedded?(str)
+  end
+
   WCHARS = [Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE]
 
   def test_wchar_embed
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 53723)
+++ ChangeLog	(revision 53724)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Feb  3 12:13:20 2016  NARUSE, Yui  <naruse@r...>
+
+	* string.c (str_new_frozen): if the given string is embeddedable
+	  but not embedded, embed a new copied string. [Bug #11946]
+
 Wed Feb  3 08:25:38 2016  boshan  <boshan@s...>
 
 	* ext/openssl/ossl_pkey.c (Init_ossl_pkey): [DOC] Fix typo
Index: ext/-test-/string/cstr.c
===================================================================
--- ext/-test-/string/cstr.c	(revision 53723)
+++ ext/-test-/string/cstr.c	(revision 53724)
@@ -1,5 +1,4 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/string/cstr.c#L1
-#include "ruby.h"
-#include "ruby/encoding.h"
+#include "internal.h"
 
 static VALUE
 bug_str_cstr_term(VALUE str)
@@ -71,6 +70,44 @@ bug_str_s_cstr_term_char(VALUE self, VAL https://github.com/ruby/ruby/blob/trunk/ext/-test-/string/cstr.c#L70
     return bug_str_cstr_term_char(str);
 }
 
+#define TERM_LEN(str) rb_enc_mbminlen(rb_enc_get(str))
+#define TERM_FILL(ptr, termlen) do {\
+    char *const term_fill_ptr = (ptr);\
+    const int term_fill_len = (termlen);\
+    *term_fill_ptr = '\0';\
+    if (UNLIKELY(term_fill_len > 1))\
+	memset(term_fill_ptr, 0, term_fill_len);\
+} while (0)
+
+static VALUE
+bug_str_s_cstr_noembed(VALUE self, VALUE str)
+{
+    VALUE str2 = rb_str_new(NULL, 0);
+    long capacity = RSTRING_LEN(str) + TERM_LEN(str);
+    char *buf = ALLOC_N(char, capacity);
+    Check_Type(str, T_STRING);
+    FL_SET((str2), STR_NOEMBED);
+    memcpy(buf, RSTRING_PTR(str), capacity);
+    RBASIC(str2)->flags &= ~RSTRING_EMBED_LEN_MASK;
+    RSTRING(str2)->as.heap.aux.capa = capacity;
+    RSTRING(str2)->as.heap.ptr = buf;
+    RSTRING(str2)->as.heap.len = RSTRING_LEN(str);
+    TERM_FILL(RSTRING_END(str2), TERM_LEN(str));
+    return str2;
+}
+
+static VALUE
+bug_str_s_cstr_embedded_p(VALUE self, VALUE str)
+{
+    return STR_EMBED_P(str) ? Qtrue : Qfalse;
+}
+
+static VALUE
+bug_str_s_rb_str_new_frozen(VALUE self, VALUE str)
+{
+    return rb_str_new_frozen(str);
+}
+
 void
 Init_cstr(VALUE klass)
 {
@@ -80,4 +117,7 @@ Init_cstr(VALUE klass) https://github.com/ruby/ruby/blob/trunk/ext/-test-/string/cstr.c#L117
     rb_define_singleton_method(klass, "cstr_term", bug_str_s_cstr_term, 1);
     rb_define_singleton_method(klass, "cstr_unterm", bug_str_s_cstr_unterm, 2);
     rb_define_singleton_method(klass, "cstr_term_char", bug_str_s_cstr_term_char, 1);
+    rb_define_singleton_method(klass, "cstr_noembed", bug_str_s_cstr_noembed, 1);
+    rb_define_singleton_method(klass, "cstr_embedded?", bug_str_s_cstr_embedded_p, 1);
+    rb_define_singleton_method(klass, "rb_str_new_frozen", bug_str_s_rb_str_new_frozen, 1);
 }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]