aboutsummaryrefslogtreecommitdiff
path: root/ui-snapshot.c
diff options
context:
space:
mode:
authorJohn Keeping <john@keeping.me.uk>2013-04-06 10:28:57 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2013-04-08 16:12:52 +0200
commitfb3655df3bf85bd405c5921bbd4b3a54c705c839 (patch)
tree419a962a0b82f5ba3023791549044ff462229250 /ui-snapshot.c
parent42d5476f258e7909682f1b611da00d64507d45c6 (diff)
downloadcgit-fb3655df3bf85bd405c5921bbd4b3a54c705c839.tar.gz
cgit-fb3655df3bf85bd405c5921bbd4b3a54c705c839.tar.bz2
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 @@
static int write_archive_type(const char *format, const char *hex, const char *prefix)
{
struct argv_array argv = ARGV_ARRAY_INIT;
+ const char **nargv;
+ int result;
argv_array_push(&argv, "snapshot");
argv_array_push(&argv, format);
if (prefix) {
+ struct strbuf buf = STRBUF_INIT;
+ strbuf_addstr(&buf, prefix);
+ strbuf_addch(&buf, '/');
argv_array_push(&argv, "--prefix");
- argv_array_push(&argv, fmt("%s/", prefix));
+ argv_array_push(&argv, buf.buf);
+ strbuf_release(&buf);
}
argv_array_push(&argv, hex);
- return write_archive(argv.argc, argv.argv, NULL, 1, NULL, 0);
+ /*
+ * Now we need to copy the pointers to arguments into a new
+ * structure because write_archive will rearrange its arguments
+ * which may result in duplicated/missing entries causing leaks
+ * or double-frees in argv_array_clear.
+ */
+ nargv = xmalloc(sizeof(char *) * (argv.argc + 1));
+ /* argv_array guarantees a trailing NULL entry. */
+ memcpy(nargv, argv.argv, sizeof(char *) * (argv.argc + 1));
+
+ result = write_archive(argv.argc, nargv, NULL, 1, NULL, 0);
+ argv_array_clear(&argv);
+ free(nargv);
+ return result;
}
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,
{
const char *reponame;
unsigned char sha1[20];
- char *snapshot;
+ struct strbuf snapshot = STRBUF_INIT;
+ int result = 1;
- snapshot = xstrdup(filename);
- snapshot[strlen(snapshot) - strlen(format->suffix)] = '\0';
+ strbuf_addstr(&snapshot, filename);
+ strbuf_setlen(&snapshot, snapshot.len - strlen(format->suffix));
- if (get_sha1(snapshot, sha1) == 0)
- return snapshot;
+ if (get_sha1(snapshot.buf, sha1) == 0)
+ goto out;
reponame = cgit_repobasename(url);
- if (prefixcmp(snapshot, reponame) == 0) {
- snapshot += strlen(reponame);
- while (snapshot && (*snapshot == '-' || *snapshot == '_'))
- snapshot++;
+ if (prefixcmp(snapshot.buf, reponame) == 0) {
+ const char *new_start = snapshot.buf;
+ new_start += strlen(reponame);
+ while (new_start && (*new_start == '-' || *new_start == '_'))
+ new_start++;
+ strbuf_splice(&snapshot, 0, new_start - snapshot.buf, "", 0);
}
- if (get_sha1(snapshot, sha1) == 0)
- return snapshot;
+ if (get_sha1(snapshot.buf, sha1) == 0)
+ goto out;
- snapshot = fmt("v%s", snapshot);
- if (get_sha1(snapshot, sha1) == 0)
- return snapshot;
+ strbuf_insert(&snapshot, 0, "v", 1);
+ if (get_sha1(snapshot.buf, sha1) == 0)
+ goto out;
- return NULL;
+ result = 0;
+ strbuf_release(&snapshot);
+
+out:
+ return result ? strbuf_detach(&snapshot, NULL) : NULL;
}
__attribute__((format (printf, 1, 2)))