diff options
author | shirosaki <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-09-25 15:31:01 +0000 |
---|---|---|
committer | shirosaki <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-09-25 15:31:01 +0000 |
commit | b14325443a1e868100c3a5fa4365223b61a77f08 (patch) | |
tree | fd43f3015315ae961368e50ba8df2e15e7095ca1 /dir.c | |
parent | 7ef91e62e284436aff20f69f54e251331df900b9 (diff) | |
download | ruby-b14325443a1e868100c3a5fa4365223b61a77f08.tar.gz |
dir.c: fix memory leak of glob with braces
join_path uses malloc. So free is required.
[Feature #13167]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64835 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'dir.c')
-rw-r--r-- | dir.c | 30 |
1 files changed, 25 insertions, 5 deletions
@@ -2055,11 +2055,12 @@ dirent_match_brace(const char *pattern, VALUE val, void *enc) } /* join paths from pattern list of glob_make_pattern() */ -static const char* +static char* join_path_from_pattern(struct glob_pattern **beg) { struct glob_pattern *p; - const char *path = ""; + char *path = NULL; + size_t path_len; for (p = *beg; p; p = p->next) { const char *str; @@ -2070,7 +2071,23 @@ join_path_from_pattern(struct glob_pattern **beg) default: str = p->str; } - path = join_path(path, strlen(path), (p != *beg), str, strlen(str)); + if (!path) { + path_len = strlen(str); + path = GLOB_ALLOC_N(char, path_len + 1); + memcpy(path, str, path_len); + path[path_len] = '\0'; + } else { + size_t len = strlen(str); + char *tmp; + tmp = GLOB_REALLOC(path, path_len + len + 2); + if (tmp) { + path = tmp; + path[path_len++] = '/'; + memcpy(path + path_len, str, len); + path_len += len; + path[path_len] = '\0'; + } + } } return path; } @@ -2138,7 +2155,8 @@ glob_helper( if (brace) { struct push_glob_args args; - const char* brace_path = join_path_from_pattern(beg); + char* brace_path = join_path_from_pattern(beg); + if (!brace_path) return -1; args.fd = fd; args.path = path; args.baselen = baselen; @@ -2147,7 +2165,9 @@ glob_helper( args.flags = flags; args.funcs = funcs; args.arg = arg; - return ruby_brace_expand(brace_path, flags, push_caller, (VALUE)&args, enc, Qfalse); + status = ruby_brace_expand(brace_path, flags, push_caller, (VALUE)&args, enc, Qfalse); + GLOB_FREE(brace_path); + return status; } if (*path) { |