diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2014-03-04 20:09:17 +0100 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2014-03-04 20:11:50 +0100 |
commit | a14aa1e789aca48660466f37b2804b6a9d88e1c8 (patch) | |
tree | 8452ecf3547d2839ae115ef29068022c322ff9e2 | |
parent | bb3687c5a8180c39d12b437ca1822ac43482b26f (diff) | |
download | libgit2-a14aa1e789aca48660466f37b2804b6a9d88e1c8.tar.gz |
pack-objects: free memory safely
A few fixes have accumulated in this area which have made the freeing of
data a bit muddy. Make sure to free the data only when needed and once.
When we are going to write a delta to the packfile, we need to free the
data, otherwise leave it. The current version of the code mixes up the
checks for po->data and po->delta_data.
-rw-r--r-- | src/pack-objects.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/src/pack-objects.c b/src/pack-objects.c index 8b65ac26a..c881e6d99 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -288,18 +288,21 @@ static int write_object( git_odb_object *obj = NULL; git_otype type; unsigned char hdr[10], *zbuf = NULL; - void *delta_data = NULL; - void *data; + void *data = NULL; size_t hdr_len, zbuf_len = COMPRESS_BUFLEN, data_len; int error; + /* + * If we have a delta base, let's use the delta to save space. + * Otherwise load the whole object. 'data' ends up pointing to + * whatever data we want to put into the packfile. + */ if (po->delta) { if (po->delta_data) - delta_data = po->delta_data; - else if ((error = get_delta(&delta_data, pb->odb, po)) < 0) + data = po->delta_data; + else if ((error = get_delta(&data, pb->odb, po)) < 0) goto done; - data = delta_data; data_len = po->delta_size; type = GIT_OBJ_REF_DELTA; } else { @@ -346,13 +349,17 @@ static int write_object( zbuf_len = COMPRESS_BUFLEN; /* reuse buffer */ } - - if (po->delta) - git__free(delta_data); } - if (po->delta_data) { - git__free(po->delta_data); + /* + * If po->delta is true, data is a delta and it is our + * responsibility to free it (otherwise it's a git_object's + * data). We set po->delta_data to NULL in case we got the + * data from there instead of get_delta(). If we didn't, + * there's no harm. + */ + if (po->delta) { + git__free(data); po->delta_data = NULL; } |