Add REALLOC macro to simplify realloc error handling
realloc can fail just like the other memory allocation functions. Add a macro to simplify handling of realloc failures, similar to the already existing MALLOC, CALLOC, etc. Replace the existing realloc uses with the new macro, allowing us to move tedious error handling to the macro. Also, in be_package and be_sync, this fixes hypothetical memory leaks (and thereafter null pointer dereferences) in case realloc fails to shrink the allocated memory. Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com> Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
parent
1d39557aa0
commit
1b32897453
5 changed files with 7 additions and 19 deletions
|
@ -843,12 +843,7 @@ static int local_db_read(alpm_pkg_t *info, int inforeq)
|
||||||
}
|
}
|
||||||
/* attempt to hand back any memory we don't need */
|
/* attempt to hand back any memory we don't need */
|
||||||
if(files_count > 0) {
|
if(files_count > 0) {
|
||||||
alpm_file_t *newfiles;
|
REALLOC(files, sizeof(alpm_file_t) * files_count, (void)0);
|
||||||
|
|
||||||
newfiles = realloc(files, sizeof(alpm_file_t) * files_count);
|
|
||||||
if(newfiles != NULL) {
|
|
||||||
files = newfiles;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
FREE(files);
|
FREE(files);
|
||||||
}
|
}
|
||||||
|
|
|
@ -669,8 +669,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
|
||||||
if(full) {
|
if(full) {
|
||||||
if(newpkg->files.files) {
|
if(newpkg->files.files) {
|
||||||
/* attempt to hand back any memory we don't need */
|
/* attempt to hand back any memory we don't need */
|
||||||
newpkg->files.files = realloc(newpkg->files.files,
|
REALLOC(newpkg->files.files, sizeof(alpm_file_t) * newpkg->files.count, (void)0);
|
||||||
sizeof(alpm_file_t) * newpkg->files.count);
|
|
||||||
/* "checking for conflicts" requires a sorted list, ensure that here */
|
/* "checking for conflicts" requires a sorted list, ensure that here */
|
||||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||||
"sorting package filelist for %s\n", pkgfile);
|
"sorting package filelist for %s\n", pkgfile);
|
||||||
|
|
|
@ -689,7 +689,7 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||||
}
|
}
|
||||||
/* attempt to hand back any memory we don't need */
|
/* attempt to hand back any memory we don't need */
|
||||||
if(files_count > 0) {
|
if(files_count > 0) {
|
||||||
files = realloc(files, sizeof(alpm_file_t) * files_count);
|
REALLOC(files, sizeof(alpm_file_t) * files_count, (void)0);
|
||||||
} else {
|
} else {
|
||||||
FREE(files);
|
FREE(files);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1427,22 +1427,15 @@ int _alpm_fnmatch(const void *pattern, const void *string)
|
||||||
*/
|
*/
|
||||||
void *_alpm_realloc(void **data, size_t *current, const size_t required)
|
void *_alpm_realloc(void **data, size_t *current, const size_t required)
|
||||||
{
|
{
|
||||||
char *newdata;
|
REALLOC(*data, required, return NULL);
|
||||||
|
|
||||||
newdata = realloc(*data, required);
|
|
||||||
if(!newdata) {
|
|
||||||
_alpm_alloc_fail(required);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*current < required) {
|
if (*current < required) {
|
||||||
/* ensure all new memory is zeroed out, in both the initial
|
/* ensure all new memory is zeroed out, in both the initial
|
||||||
* allocation and later reallocs */
|
* allocation and later reallocs */
|
||||||
memset(newdata + *current, 0, required - *current);
|
memset((char*)*data + *current, 0, required - *current);
|
||||||
}
|
}
|
||||||
*current = required;
|
*current = required;
|
||||||
*data = newdata;
|
return *data;
|
||||||
return newdata;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This automatically grows data based on current/required.
|
/** This automatically grows data based on current/required.
|
||||||
|
|
|
@ -53,6 +53,7 @@ void _alpm_alloc_fail(size_t size);
|
||||||
|
|
||||||
#define MALLOC(p, s, action) do { p = malloc(s); if(p == NULL) { _alpm_alloc_fail(s); action; } } while(0)
|
#define MALLOC(p, s, action) do { p = malloc(s); if(p == NULL) { _alpm_alloc_fail(s); action; } } while(0)
|
||||||
#define CALLOC(p, l, s, action) do { p = calloc(l, s); if(p == NULL) { _alpm_alloc_fail(l * s); action; } } while(0)
|
#define CALLOC(p, l, s, action) do { p = calloc(l, s); if(p == NULL) { _alpm_alloc_fail(l * s); action; } } while(0)
|
||||||
|
#define REALLOC(p, s, action) do { void* np = realloc(p, s); if(np == NULL) { _alpm_alloc_fail(s); action; } else { p = np; } } while(0)
|
||||||
/* This strdup macro is NULL safe- copying NULL will yield NULL */
|
/* This strdup macro is NULL safe- copying NULL will yield NULL */
|
||||||
#define STRDUP(r, s, action) do { if(s != NULL) { r = strdup(s); if(r == NULL) { _alpm_alloc_fail(strlen(s)); action; } } else { r = NULL; } } while(0)
|
#define STRDUP(r, s, action) do { if(s != NULL) { r = strdup(s); if(r == NULL) { _alpm_alloc_fail(strlen(s)); action; } } else { r = NULL; } } while(0)
|
||||||
#define STRNDUP(r, s, l, action) do { if(s != NULL) { r = strndup(s, l); if(r == NULL) { _alpm_alloc_fail(l); action; } } else { r = NULL; } } while(0)
|
#define STRNDUP(r, s, l, action) do { if(s != NULL) { r = strndup(s, l); if(r == NULL) { _alpm_alloc_fail(l); action; } } else { r = NULL; } } while(0)
|
||||||
|
|
Loading…
Add table
Reference in a new issue