diff options
Diffstat (limited to 'ui-snapshot.c')
-rw-r--r-- | ui-snapshot.c | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/ui-snapshot.c b/ui-snapshot.c index a47884e..8e76977 100644 --- a/ui-snapshot.c +++ b/ui-snapshot.c | |||
@@ -15,14 +15,33 @@ | |||
15 | static int write_archive_type(const char *format, const char *hex, const char *prefix) | 15 | static int write_archive_type(const char *format, const char *hex, const char *prefix) |
16 | { | 16 | { |
17 | struct argv_array argv = ARGV_ARRAY_INIT; | 17 | struct argv_array argv = ARGV_ARRAY_INIT; |
18 | const char **nargv; | ||
19 | int result; | ||
18 | argv_array_push(&argv, "snapshot"); | 20 | argv_array_push(&argv, "snapshot"); |
19 | argv_array_push(&argv, format); | 21 | argv_array_push(&argv, format); |
20 | if (prefix) { | 22 | if (prefix) { |
23 | struct strbuf buf = STRBUF_INIT; | ||
24 | strbuf_addstr(&buf, prefix); | ||
25 | strbuf_addch(&buf, '/'); | ||
21 | argv_array_push(&argv, "--prefix"); | 26 | argv_array_push(&argv, "--prefix"); |
22 | argv_array_push(&argv, fmt("%s/", prefix)); | 27 | argv_array_push(&argv, buf.buf); |
28 | strbuf_release(&buf); | ||
23 | } | 29 | } |
24 | argv_array_push(&argv, hex); | 30 | argv_array_push(&argv, hex); |
25 | return write_archive(argv.argc, argv.argv, NULL, 1, NULL, 0); | 31 | /* |
32 | * Now we need to copy the pointers to arguments into a new | ||
33 | * structure because write_archive will rearrange its arguments | ||
34 | * which may result in duplicated/missing entries causing leaks | ||
35 | * or double-frees in argv_array_clear. | ||
36 | */ | ||
37 | nargv = xmalloc(sizeof(char *) * (argv.argc + 1)); | ||
38 | /* argv_array guarantees a trailing NULL entry. */ | ||
39 | memcpy(nargv, argv.argv, sizeof(char *) * (argv.argc + 1)); | ||
40 | |||
41 | result = write_archive(argv.argc, nargv, NULL, 1, NULL, 0); | ||
42 | argv_array_clear(&argv); | ||
43 | free(nargv); | ||
44 | return result; | ||
26 | } | 45 | } |
27 | 46 | ||
28 | static int write_tar_archive(const char *hex, const char *prefix) | 47 | static int write_tar_archive(const char *hex, const char *prefix) |
@@ -129,29 +148,36 @@ static const char *get_ref_from_filename(const char *url, const char *filename, | |||
129 | { | 148 | { |
130 | const char *reponame; | 149 | const char *reponame; |
131 | unsigned char sha1[20]; | 150 | unsigned char sha1[20]; |
132 | char *snapshot; | 151 | struct strbuf snapshot = STRBUF_INIT; |
152 | int result = 1; | ||
133 | 153 | ||
134 | snapshot = xstrdup(filename); | 154 | strbuf_addstr(&snapshot, filename); |
135 | snapshot[strlen(snapshot) - strlen(format->suffix)] = '\0'; | 155 | strbuf_setlen(&snapshot, snapshot.len - strlen(format->suffix)); |
136 | 156 | ||
137 | if (get_sha1(snapshot, sha1) == 0) | 157 | if (get_sha1(snapshot.buf, sha1) == 0) |
138 | return snapshot; | 158 | goto out; |
139 | 159 | ||
140 | reponame = cgit_repobasename(url); | 160 | reponame = cgit_repobasename(url); |
141 | if (prefixcmp(snapshot, reponame) == 0) { | 161 | if (prefixcmp(snapshot.buf, reponame) == 0) { |
142 | snapshot += strlen(reponame); | 162 | const char *new_start = snapshot.buf; |
143 | while (snapshot && (*snapshot == '-' || *snapshot == '_')) | 163 | new_start += strlen(reponame); |
144 | snapshot++; | 164 | while (new_start && (*new_start == '-' || *new_start == '_')) |
165 | new_start++; | ||
166 | strbuf_splice(&snapshot, 0, new_start - snapshot.buf, "", 0); | ||
145 | } | 167 | } |
146 | 168 | ||
147 | if (get_sha1(snapshot, sha1) == 0) | 169 | if (get_sha1(snapshot.buf, sha1) == 0) |
148 | return snapshot; | 170 | goto out; |
149 | 171 | ||
150 | snapshot = fmt("v%s", snapshot); | 172 | strbuf_insert(&snapshot, 0, "v", 1); |
151 | if (get_sha1(snapshot, sha1) == 0) | 173 | if (get_sha1(snapshot.buf, sha1) == 0) |
152 | return snapshot; | 174 | goto out; |
153 | 175 | ||
154 | return NULL; | 176 | result = 0; |
177 | strbuf_release(&snapshot); | ||
178 | |||
179 | out: | ||
180 | return result ? strbuf_detach(&snapshot, NULL) : NULL; | ||
155 | } | 181 | } |
156 | 182 | ||
157 | __attribute__((format (printf, 1, 2))) | 183 | __attribute__((format (printf, 1, 2))) |