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 = ¤t_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/