summaryrefslogtreecommitdiff
path: root/commit.c
diff options
context:
space:
mode:
authorLibravatar Jeff King <peff@peff.net>2014-06-10 17:44:13 -0400
committerLibravatar Junio C Hamano <gitster@pobox.com>2014-06-13 12:09:38 -0700
commit8597ea3afea067b39ba7d4adae7ec6c1ee0e7c91 (patch)
tree01419168b4f08949baeabe5b8650066e6a92732c /commit.c
parentcommit: convert commit->buffer to a slab (diff)
downloadtgif-8597ea3afea067b39ba7d4adae7ec6c1ee0e7c91.tar.xz
commit: record buffer length in cache
Most callsites which use the commit buffer try to use the cached version attached to the commit, rather than re-reading from disk. Unfortunately, that interface provides only a pointer to the NUL-terminated buffer, with no indication of the original length. For the most part, this doesn't matter. People do not put NULs in their commit messages, and the log code is happy to treat it all as a NUL-terminated string. However, some code paths do care. For example, when checking signatures, we want to be very careful that we verify all the bytes to avoid malicious trickery. This patch just adds an optional "size" out-pointer to get_commit_buffer and friends. The existing callers all pass NULL (there did not seem to be any obvious sites where we could avoid an immediate strlen() call, though perhaps with some further refactoring we could). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'commit.c')
-rw-r--r--commit.c54
1 files changed, 36 insertions, 18 deletions
diff --git a/commit.c b/commit.c
index e289c78327..a036e181c7 100644
--- a/commit.c
+++ b/commit.c
@@ -245,22 +245,31 @@ int unregister_shallow(const unsigned char *sha1)
return 0;
}
-define_commit_slab(buffer_slab, void *);
+struct commit_buffer {
+ void *buffer;
+ unsigned long size;
+};
+define_commit_slab(buffer_slab, struct commit_buffer);
static struct buffer_slab buffer_slab = COMMIT_SLAB_INIT(1, buffer_slab);
-void set_commit_buffer(struct commit *commit, void *buffer)
+void set_commit_buffer(struct commit *commit, void *buffer, unsigned long size)
{
- *buffer_slab_at(&buffer_slab, commit) = buffer;
+ struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ v->buffer = buffer;
+ v->size = size;
}
-const void *get_cached_commit_buffer(const struct commit *commit)
+const void *get_cached_commit_buffer(const struct commit *commit, unsigned long *sizep)
{
- return *buffer_slab_at(&buffer_slab, commit);
+ struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ if (sizep)
+ *sizep = v->size;
+ return v->buffer;
}
-const void *get_commit_buffer(const struct commit *commit)
+const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep)
{
- const void *ret = get_cached_commit_buffer(commit);
+ const void *ret = get_cached_commit_buffer(commit, sizep);
if (!ret) {
enum object_type type;
unsigned long size;
@@ -271,29 +280,38 @@ const void *get_commit_buffer(const struct commit *commit)
if (type != OBJ_COMMIT)
die("expected commit for %s, got %s",
sha1_to_hex(commit->object.sha1), typename(type));
+ if (sizep)
+ *sizep = size;
}
return ret;
}
void unuse_commit_buffer(const struct commit *commit, const void *buffer)
{
- void *cached = *buffer_slab_at(&buffer_slab, commit);
- if (cached != buffer)
+ struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ if (v->buffer != buffer)
free((void *)buffer);
}
void free_commit_buffer(struct commit *commit)
{
- void **b = buffer_slab_at(&buffer_slab, commit);
- free(*b);
- *b = NULL;
+ struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ free(v->buffer);
+ v->buffer = NULL;
+ v->size = 0;
}
-const void *detach_commit_buffer(struct commit *commit)
+const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep)
{
- void **b = buffer_slab_at(&buffer_slab, commit);
- void *ret = *b;
- *b = NULL;
+ struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ void *ret;
+
+ ret = v->buffer;
+ if (sizep)
+ *sizep = v->size;
+
+ v->buffer = NULL;
+ v->size = 0;
return ret;
}
@@ -374,7 +392,7 @@ int parse_commit(struct commit *item)
}
ret = parse_commit_buffer(item, buffer, size);
if (save_commit_buffer && !ret) {
- set_commit_buffer(item, buffer);
+ set_commit_buffer(item, buffer, size);
return 0;
}
free(buffer);
@@ -589,7 +607,7 @@ static void record_author_date(struct author_date_slab *author_date,
struct commit *commit)
{
const char *buf, *line_end, *ident_line;
- const char *buffer = get_commit_buffer(commit);
+ const char *buffer = get_commit_buffer(commit, NULL);
struct ident_split ident;
char *date_end;
unsigned long date;