summaryrefslogtreecommitdiff
path: root/dir.c
diff options
context:
space:
mode:
authorshirosaki <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-09-25 15:31:01 +0000
committershirosaki <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-09-25 15:31:01 +0000
commitb14325443a1e868100c3a5fa4365223b61a77f08 (patch)
treefd43f3015315ae961368e50ba8df2e15e7095ca1 /dir.c
parent7ef91e62e284436aff20f69f54e251331df900b9 (diff)
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.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/dir.c b/dir.c
index fe4ec909ae..6c6b40e694 100644
--- a/dir.c
+++ b/dir.c
@@ -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) {