mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-29 10:03:43 +00:00
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.
This commit is contained in:
parent
bb3687c5a8
commit
a14aa1e789
@ -288,18 +288,21 @@ static int write_object(
|
|||||||
git_odb_object *obj = NULL;
|
git_odb_object *obj = NULL;
|
||||||
git_otype type;
|
git_otype type;
|
||||||
unsigned char hdr[10], *zbuf = NULL;
|
unsigned char hdr[10], *zbuf = NULL;
|
||||||
void *delta_data = NULL;
|
void *data = NULL;
|
||||||
void *data;
|
|
||||||
size_t hdr_len, zbuf_len = COMPRESS_BUFLEN, data_len;
|
size_t hdr_len, zbuf_len = COMPRESS_BUFLEN, data_len;
|
||||||
int error;
|
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) {
|
||||||
if (po->delta_data)
|
if (po->delta_data)
|
||||||
delta_data = po->delta_data;
|
data = po->delta_data;
|
||||||
else if ((error = get_delta(&delta_data, pb->odb, po)) < 0)
|
else if ((error = get_delta(&data, pb->odb, po)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
data = delta_data;
|
|
||||||
data_len = po->delta_size;
|
data_len = po->delta_size;
|
||||||
type = GIT_OBJ_REF_DELTA;
|
type = GIT_OBJ_REF_DELTA;
|
||||||
} else {
|
} else {
|
||||||
@ -346,13 +349,17 @@ static int write_object(
|
|||||||
|
|
||||||
zbuf_len = COMPRESS_BUFLEN; /* reuse buffer */
|
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;
|
po->delta_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user