mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
merge revision(s) 5e23b1138f [backport #15820]
Fix potential memory leak git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@67753 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
59ed372bcb
commit
d65f94634c
2 changed files with 33 additions and 18 deletions
49
string.c
49
string.c
|
|
@ -6374,6 +6374,23 @@ typedef struct mapping_buffer {
|
|||
OnigUChar space[1];
|
||||
} 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)
|
||||
{
|
||||
|
|
@ -6381,8 +6398,9 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc)
|
|||
|
||||
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;
|
||||
|
||||
|
|
@ -6391,14 +6409,17 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc)
|
|||
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,
|
||||
|
|
@ -6407,14 +6428,9 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc)
|
|||
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;
|
||||
xfree(previous_buffer);
|
||||
}
|
||||
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;
|
||||
|
|
@ -6425,23 +6441,22 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc)
|
|||
|
||||
if (buffer_count==1) {
|
||||
target = rb_str_new_with_class(source, (const char*)current_buffer->space, target_length);
|
||||
xfree(current_buffer);
|
||||
}
|
||||
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;
|
||||
xfree(previous_buffer);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#define RUBY_VERSION "2.5.6"
|
||||
#define RUBY_RELEASE_DATE "2019-08-26"
|
||||
#define RUBY_PATCHLEVEL 172
|
||||
#define RUBY_PATCHLEVEL 173
|
||||
|
||||
#define RUBY_RELEASE_YEAR 2019
|
||||
#define RUBY_RELEASE_MONTH 8
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue