From e0acf2f144404e613a75d5aafea2a909989544e9 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 28 Sep 2011 12:58:43 -0500 Subject: Refactor download payload reset and free This was done to squash a memory leak in the sync database download code. When we downloaded a database and then reused the payload struct, we could find ourselves calling get_fullpath() for the signatures and overwriting non-freed values we had left over from the database download. Refactor the payload_free function into a payload_reset function that we can call that does NOT free the payload itself, so we can reuse payload structs. This also allows us to move the payload to the stack in some call paths, relieving us of the need to alloc space. Signed-off-by: Dan McGee --- lib/libalpm/be_sync.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'lib/libalpm/be_sync.c') diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index 53777d92..e9e816c0 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -201,24 +201,25 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) for(i = db->servers; i; i = i->next) { const char *server = i->data; - struct dload_payload *payload; + struct dload_payload payload; size_t len; int sig_ret = 0; - CALLOC(payload, 1, sizeof(*payload), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); + memset(&payload, 0, sizeof(struct dload_payload)); /* set hard upper limit of 25MiB */ - payload->max_size = 25 * 1024 * 1024; + payload.max_size = 25 * 1024 * 1024; - /* print server + filename into a buffer (leave space for .sig) */ - len = strlen(server) + strlen(db->treename) + 9; - CALLOC(payload->fileurl, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1)); - snprintf(payload->fileurl, len, "%s/%s.db", server, db->treename); - payload->handle = handle; - payload->force = force; - payload->unlink_on_fail = 1; + /* print server + filename into a buffer */ + len = strlen(server) + strlen(db->treename) + 5; + MALLOC(payload.fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); + snprintf(payload.fileurl, len, "%s/%s.db", server, db->treename); + payload.handle = handle; + payload.force = force; + payload.unlink_on_fail = 1; - ret = _alpm_download(payload, syncpath, NULL); + ret = _alpm_download(&payload, syncpath, NULL); + _alpm_dload_payload_reset(&payload); if(ret == 0 && (level & ALPM_SIG_DATABASE)) { /* an existing sig file is no good at this point */ @@ -231,20 +232,23 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) free(sigpath); /* if we downloaded a DB, we want the .sig from the same server */ - snprintf(payload->fileurl, len, "%s/%s.db.sig", server, db->treename); - payload->handle = handle; - payload->force = 1; - payload->errors_ok = (level & ALPM_SIG_DATABASE_OPTIONAL); + /* print server + filename into a buffer (leave space for .sig) */ + len = strlen(server) + strlen(db->treename) + 9; + MALLOC(payload.fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); + snprintf(payload.fileurl, len, "%s/%s.db.sig", server, db->treename); + payload.handle = handle; + payload.force = 1; + payload.errors_ok = (level & ALPM_SIG_DATABASE_OPTIONAL); /* set hard upper limit of 16KiB */ - payload->max_size = 16 * 1024; + payload.max_size = 16 * 1024; - sig_ret = _alpm_download(payload, syncpath, NULL); + sig_ret = _alpm_download(&payload, syncpath, NULL); /* errors_ok suppresses error messages, but not the return code */ - sig_ret = payload->errors_ok ? 0 : sig_ret; + sig_ret = payload.errors_ok ? 0 : sig_ret; + _alpm_dload_payload_reset(&payload); } - _alpm_dload_payload_free(payload); if(ret != -1 && sig_ret != -1) { break; } -- cgit v1.2.3-24-g4f1b