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

ruby-changes:56191

From: nagachika <ko1@a...>
Date: Sat, 22 Jun 2019 10:56:24 +0900 (JST)
Subject: [ruby-changes:56191] nagachika: f5022fcf06 (ruby_2_6): merge revision(s) 5e23b1138f16af0defb184d7deeffadfd2ce3c04: [Backport #15820]

https://git.ruby-lang.org/ruby.git/commit/?id=f5022fcf06

From f5022fcf06982ab54fbf32848e3ae6d3234f070d Mon Sep 17 00:00:00 2001
From: nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Sat, 22 Jun 2019 01:56:07 +0000
Subject: merge revision(s) 5e23b1138f16af0defb184d7deeffadfd2ce3c04: [Backport
 #15820]

	Fix potential memory leak


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67712 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

diff --git a/string.c b/string.c
index 855d594..156d124 100644
--- a/string.c
+++ b/string.c
@@ -6448,6 +6448,23 @@ typedef struct mapping_buffer { https://github.com/ruby/ruby/blob/trunk/string.c#L6448
     OnigUChar space[FLEX_ARY_LEN];
 } mapping_buffer;
 
+static void
+mapping_buffer_free(void *p)
+{
+    mapping_buffer *previous_buffer;
+    mapping_buffer *current_buffer = p;
+    while (current_buffer) {
+        previous_buffer = current_buffer;
+        current_buffer  = current_buffer->next;
+        ruby_sized_xfree(previous_buffer, previous_buffer->capa);
+    }
+}
+
+static const rb_data_type_t mapping_buffer_type = {
+    "mapping_buffer",
+    {0, mapping_buffer_free,}
+};
+
 static VALUE
 rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc)
 {
@@ -6455,8 +6472,9 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc) https://github.com/ruby/ruby/blob/trunk/string.c#L6472
 
     OnigUChar *source_current, *source_end;
     int target_length = 0;
-    mapping_buffer pre_buffer, /* only next pointer used */
-		  *current_buffer = &pre_buffer;
+    VALUE buffer_anchor;
+    mapping_buffer *current_buffer = 0;
+    mapping_buffer **pre_buffer;
     size_t buffer_count = 0;
     int buffer_length_or_invalid;
 
@@ -6465,14 +6483,17 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc) https://github.com/ruby/ruby/blob/trunk/string.c#L6483
     source_current = (OnigUChar*)RSTRING_PTR(source);
     source_end = (OnigUChar*)RSTRING_END(source);
 
+    buffer_anchor = TypedData_Wrap_Struct(0, &mapping_buffer_type, 0);
+    pre_buffer = (mapping_buffer **)&DATA_PTR(buffer_anchor);
     while (source_current < source_end) {
 	/* increase multiplier using buffer count to converge quickly */
 	size_t capa = (size_t)(source_end-source_current)*++buffer_count + CASE_MAPPING_ADDITIONAL_LENGTH;
 	if (CASEMAP_DEBUG) {
 	    fprintf(stderr, "Buffer allocation, capa is %"PRIuSIZE"\n", capa); /* for tuning */
 	}
-	current_buffer->next = xmalloc(offsetof(mapping_buffer, space) + capa);
-	current_buffer = current_buffer->next;
+        current_buffer = xmalloc(offsetof(mapping_buffer, space) + capa);
+        *pre_buffer = current_buffer;
+        pre_buffer = &current_buffer->next;
 	current_buffer->next = NULL;
 	current_buffer->capa = capa;
 	buffer_length_or_invalid = enc->case_map(flags,
@@ -6481,14 +6502,9 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc) https://github.com/ruby/ruby/blob/trunk/string.c#L6502
 				   current_buffer->space+current_buffer->capa,
 				   enc);
 	if (buffer_length_or_invalid < 0) {
-	    mapping_buffer *previous_buffer;
-
-	    current_buffer = pre_buffer.next;
-	    while (current_buffer) {
-		previous_buffer = current_buffer;
-		current_buffer  = current_buffer->next;
-		ruby_sized_xfree(previous_buffer, previous_buffer->capa);
-	    }
+            current_buffer = DATA_PTR(buffer_anchor);
+            DATA_PTR(buffer_anchor) = 0;
+	    mapping_buffer_free(current_buffer);
 	    rb_raise(rb_eArgError, "input string invalid");
 	}
 	target_length  += current_buffer->used = buffer_length_or_invalid;
@@ -6499,23 +6515,22 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc) https://github.com/ruby/ruby/blob/trunk/string.c#L6515
 
     if (buffer_count==1) {
 	target = rb_str_new_with_class(source, (const char*)current_buffer->space, target_length);
-	ruby_sized_xfree(current_buffer, current_buffer->capa);
     }
     else {
 	char *target_current;
-	mapping_buffer *previous_buffer;
 
 	target = rb_str_new_with_class(source, 0, target_length);
 	target_current = RSTRING_PTR(target);
-	current_buffer=pre_buffer.next;
+	current_buffer = DATA_PTR(buffer_anchor);
 	while (current_buffer) {
 	    memcpy(target_current, current_buffer->space, current_buffer->used);
 	    target_current += current_buffer->used;
-	    previous_buffer = current_buffer;
 	    current_buffer  = current_buffer->next;
-	    ruby_sized_xfree(previous_buffer, previous_buffer->capa);
 	}
     }
+    current_buffer = DATA_PTR(buffer_anchor);
+    DATA_PTR(buffer_anchor) = 0;
+    mapping_buffer_free(current_buffer);
 
     /* TODO: check about string terminator character */
     OBJ_INFECT_RAW(target, source);
diff --git a/version.h b/version.h
index b31b267..6594e9c 100644
--- a/version.h
+++ b/version.h
@@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L1
 #define RUBY_VERSION "2.6.3"
 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 64
+#define RUBY_PATCHLEVEL 65
 
 #define RUBY_RELEASE_YEAR 2019
 #define RUBY_RELEASE_MONTH 6
-#define RUBY_RELEASE_DAY 16
+#define RUBY_RELEASE_DAY 22
 
 #include "ruby/version.h"
 
-- 
cgit v0.10.2


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

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