aboutsummaryrefslogtreecommitdiffstats
path: root/ui-snapshot.c
diff options
context:
space:
mode:
authorJohn Keeping2013-04-06 10:28:57 +0100
committerJason A. Donenfeld2013-04-08 16:12:52 +0200
commitfb3655df3bf85bd405c5921bbd4b3a54c705c839 (patch)
tree419a962a0b82f5ba3023791549044ff462229250 /ui-snapshot.c
parent42d5476f258e7909682f1b611da00d64507d45c6 (diff)
downloadcgit-fb3655df3bf85bd405c5921bbd4b3a54c705c839.tar.gz
cgit-fb3655df3bf85bd405c5921bbd4b3a54c705c839.tar.bz2
cgit-fb3655df3bf85bd405c5921bbd4b3a54c705c839.zip
use struct strbuf instead of static buffers
Use "struct strbuf" from Git to remove the limit on file path length. Notes on scan-tree: This is slightly involved since I decided to pass the strbuf into add_repo() and modify if whenever a new file name is required, which should avoid any extra allocations within that function. The pattern there is to append the filename, use it and then reset the buffer to its original length (retaining a trailing '/'). Notes on ui-snapshot: Since write_archive modifies the argv array passed to it we copy the argv_array values into a new array of char* and then free the original argv_array structure and the new array without worrying about what the values now look like. Signed-off-by: John Keeping <john@keeping.me.uk>
Diffstat (limited to 'ui-snapshot.c')
-rw-r--r--ui-snapshot.c60
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 @@
15static int write_archive_type(const char *format, const char *hex, const char *prefix) 15static 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
28static int write_tar_archive(const char *hex, const char *prefix) 47static 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
179out:
180 return result ? strbuf_detach(&snapshot, NULL) : NULL;
155} 181}
156 182
157__attribute__((format (printf, 1, 2))) 183__attribute__((format (printf, 1, 2)))