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

ruby-changes:37563

From: naruse <ko1@a...>
Date: Thu, 19 Feb 2015 15:33:27 +0900 (JST)
Subject: [ruby-changes:37563] naruse:r49644 (ruby_2_2): merge revision(s) 49405-49408:

naruse	2015-02-19 15:33:07 +0900 (Thu, 19 Feb 2015)

  New Revision: 49644

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

  Log:
    merge revision(s) 49405-49408:
    
    * string.c (str_make_independent_expand): terminate String when
      moved from heap to embedded.  [Fix GH-821].

  Modified directories:
    branches/ruby_2_2/
  Modified files:
    branches/ruby_2_2/ChangeLog
    branches/ruby_2_2/string.c
    branches/ruby_2_2/test/-ext-/string/test_cstr.rb
    branches/ruby_2_2/version.h
Index: ruby_2_2/ChangeLog
===================================================================
--- ruby_2_2/ChangeLog	(revision 49643)
+++ ruby_2_2/ChangeLog	(revision 49644)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ChangeLog#L1
+Thu Feb 19 15:32:26 2015  Dave Stevens  <dave@c...>
+
+	* string.c (str_make_independent_expand): terminate String when
+	  moved from heap to embedded.  [Fix GH-821].
+
 Thu Feb 19 13:35:21 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/sdbm/_sdbm.c: include ruby/ruby.h for PRIdPTRDIFF when a
Index: ruby_2_2/string.c
===================================================================
--- ruby_2_2/string.c	(revision 49643)
+++ ruby_2_2/string.c	(revision 49644)
@@ -98,6 +98,9 @@ VALUE rb_cSymbol; https://github.com/ruby/ruby/blob/trunk/ruby_2_2/string.c#L98
 
 #define RESIZE_CAPA(str,capacity) do {\
     const int termlen = TERM_LEN(str);\
+    RESIZE_CAPA_TERM(str,capacity,termlen);\
+} while (0)
+#define RESIZE_CAPA_TERM(str,capacity,termlen) do {\
     if (STR_EMBED_P(str)) {\
 	if ((capacity) > RSTRING_EMBED_LEN_MAX) {\
 	    char *const tmp = ALLOC_N(char, (capacity)+termlen);\
@@ -1589,10 +1592,11 @@ str_make_independent_expand(VALUE str, l https://github.com/ruby/ruby/blob/trunk/ruby_2_2/string.c#L1592
 
     if (len > capa) len = capa;
 
-    if (capa <= RSTRING_EMBED_LEN_MAX && !STR_EMBED_P(str)) {
+    if (capa + termlen - 1 <= RSTRING_EMBED_LEN_MAX && !STR_EMBED_P(str)) {
 	ptr = RSTRING(str)->as.heap.ptr;
 	STR_SET_EMBED(str);
 	memcpy(RSTRING(str)->as.ary, ptr, len);
+	TERM_FILL(RSTRING(str)->as.ary + len, termlen);
 	STR_SET_EMBED_LEN(str, len);
 	return;
     }
@@ -2166,23 +2170,30 @@ rb_str_resize(VALUE str, long len) https://github.com/ruby/ruby/blob/trunk/ruby_2_2/string.c#L2170
 static VALUE
 str_buf_cat(VALUE str, const char *ptr, long len)
 {
-    long capa, total, off = -1;
+    long capa, total, olen, off = -1;
+    char *sptr;
+    const int termlen = TERM_LEN(str);
 
-    if (ptr >= RSTRING_PTR(str) && ptr <= RSTRING_END(str)) {
-        off = ptr - RSTRING_PTR(str);
+    RSTRING_GETMEM(str, sptr, olen);
+    if (ptr >= sptr && ptr <= sptr + olen) {
+        off = ptr - sptr;
     }
     rb_str_modify(str);
     if (len == 0) return 0;
     if (STR_EMBED_P(str)) {
 	capa = RSTRING_EMBED_LEN_MAX;
+	sptr = RSTRING(str)->as.ary;
+	olen = RSTRING_EMBED_LEN(str);
     }
     else {
 	capa = RSTRING(str)->as.heap.aux.capa;
+	sptr = RSTRING(str)->as.heap.ptr;
+	olen = RSTRING(str)->as.heap.len;
     }
-    if (RSTRING_LEN(str) >= LONG_MAX - len) {
+    if (olen >= LONG_MAX - len) {
 	rb_raise(rb_eArgError, "string sizes too big");
     }
-    total = RSTRING_LEN(str)+len;
+    total = olen + len;
     if (capa <= total) {
 	while (total > capa) {
 	    if (capa > LONG_MAX / 2) {
@@ -2191,14 +2202,15 @@ str_buf_cat(VALUE str, const char *ptr, https://github.com/ruby/ruby/blob/trunk/ruby_2_2/string.c#L2202
 	    }
 	    capa = 2 * capa;
 	}
-	RESIZE_CAPA(str, capa);
+	RESIZE_CAPA_TERM(str, capa, termlen);
+	sptr = RSTRING_PTR(str);
     }
     if (off != -1) {
-        ptr = RSTRING_PTR(str) + off;
+        ptr = sptr + off;
     }
-    memcpy(RSTRING_PTR(str) + RSTRING_LEN(str), ptr, len);
+    memcpy(sptr + olen, ptr, len);
     STR_SET_LEN(str, total);
-    RSTRING_PTR(str)[total] = '\0'; /* sentinel */
+    TERM_FILL(sptr + total, termlen); /* sentinel */
 
     return str;
 }
Index: ruby_2_2/version.h
===================================================================
--- ruby_2_2/version.h	(revision 49643)
+++ ruby_2_2/version.h	(revision 49644)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_2/version.h#L1
 #define RUBY_VERSION "2.2.0"
 #define RUBY_RELEASE_DATE "2015-02-19"
-#define RUBY_PATCHLEVEL 54
+#define RUBY_PATCHLEVEL 55
 
 #define RUBY_RELEASE_YEAR 2015
 #define RUBY_RELEASE_MONTH 2
Index: ruby_2_2/test/-ext-/string/test_cstr.rb
===================================================================
--- ruby_2_2/test/-ext-/string/test_cstr.rb	(revision 49643)
+++ ruby_2_2/test/-ext-/string/test_cstr.rb	(revision 49644)
@@ -86,6 +86,26 @@ class Test_StringCStr < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/-ext-/string/test_cstr.rb#L86
     }
   end
 
+  def test_embedded_from_heap
+    gh821 = "[GH-821]"
+    embedded_string = "abcdefghi"
+    string = embedded_string.gsub("efg", "123")
+    {}[string] = 1
+    non_terminated = "#{string}#{nil}"
+    assert_nil(Bug::String.cstr_term_char(non_terminated), gh821)
+
+    result = {}
+    WCHARS.map do |enc|
+      embedded_string = "ab".encode(enc)
+      string = embedded_string.gsub("b".encode(enc), "1".encode(enc))
+      {}[string] = 1
+      non_terminated = "#{string}#{nil}"
+      c = Bug::String.cstr_term_char(non_terminated)
+      result[enc] = c if c
+    end
+    assert_empty(result, gh821)
+  end
+
   def assert_wchars_term_char(str)
     result = {}
     WCHARS.map do |enc|

Property changes on: ruby_2_2
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r49405-49408


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

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