Use a common exit path iin lrzip_compress/decompress and fix lr leak on successful return

This commit is contained in:
Con Kolivas 2015-02-09 09:19:03 +11:00
parent e21bd815a7
commit 05ae5eab75

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2012 Con Kolivas Copyright (C) 2012-2015 Con Kolivas
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -648,96 +648,94 @@ void lrzip_info_cb_set(Lrzip *lr, Lrzip_Info_Cb cb, void *data)
bool lrzip_compress_full(void *dest, unsigned long *dest_len, const void *source, unsigned long source_len, Lrzip_Mode mode, int compress_level) bool lrzip_compress_full(void *dest, unsigned long *dest_len, const void *source, unsigned long source_len, Lrzip_Mode mode, int compress_level)
{ {
Lrzip *lr; FILE *s = NULL, *d = NULL;
FILE *s, *d; Lrzip *lr = NULL;
bool ret = false;
struct stat st; struct stat st;
int fd; int fd;
if ((!dest) || (!dest_len) || (!source) || (!source_len) || (mode < LRZIP_MODE_COMPRESS_NONE)) if ((!dest) || (!dest_len) || (!source) || (!source_len) || (mode < LRZIP_MODE_COMPRESS_NONE))
return false; goto out;
lrzip_init(); lrzip_init();
if (!mode) mode = LRZIP_MODE_COMPRESS_LZMA; if (!mode) mode = LRZIP_MODE_COMPRESS_LZMA;
lr = lrzip_new(mode); lr = lrzip_new(mode);
if (!lr) if (!lr)
return false; goto out;
lrzip_config_env(lr); lrzip_config_env(lr);
s = fmemopen((void*)source, source_len, "r"); s = fmemopen((void*)source, source_len, "r");
d = tmpfile(); d = tmpfile();
if ((!s) || (!d)) if ((!s) || (!d))
goto error; goto out;
if (!lrzip_file_add(lr, s)) if (!lrzip_file_add(lr, s))
goto error; goto out;
lrzip_outfile_set(lr, d); lrzip_outfile_set(lr, d);
if (!lrzip_compression_level_set(lr, compress_level)) if (!lrzip_compression_level_set(lr, compress_level))
goto error; goto out;
if (!lrzip_run(lr)) if (!lrzip_run(lr))
goto error; goto out;
fd = fileno(d); fd = fileno(d);
if (fstat(fd, &st)) if (fstat(fd, &st))
goto error; goto out;
*dest_len = st.st_size; *dest_len = st.st_size;
if (unlikely((i64)fread(dest, sizeof(char), st.st_size, d) != st.st_size)) if (unlikely((i64)fread(dest, sizeof(char), st.st_size, d) != st.st_size))
goto error; goto out;
if (unlikely(ferror(d))) if (unlikely(ferror(d)))
goto error; goto out;
fclose(s); ret = true;
fclose(d);
return true;
error: out:
if (s) fclose(s); if (s) fclose(s);
if (d) fclose(d); if (d) fclose(d);
lrzip_free(lr); lrzip_free(lr);
return false; return ret;
} }
bool lrzip_decompress(void *dest, unsigned long *dest_len, const void *source, unsigned long source_len) bool lrzip_decompress(void *dest, unsigned long *dest_len, const void *source, unsigned long source_len)
{ {
Lrzip *lr; FILE *s = NULL, *d = NULL;
FILE *s, *d; Lrzip *lr = NULL;
bool ret = false;
struct stat st; struct stat st;
int fd; int fd;
if ((!dest) || (!dest_len) || (!source) || (!source_len)) if ((!dest) || (!dest_len) || (!source) || (!source_len))
return false; goto out;
lrzip_init(); lrzip_init();
lr = lrzip_new(LRZIP_MODE_DECOMPRESS); lr = lrzip_new(LRZIP_MODE_DECOMPRESS);
if (!lr) if (!lr)
return false; goto out;
lrzip_config_env(lr); lrzip_config_env(lr);
s = fmemopen((void*)source, source_len, "r"); s = fmemopen((void*)source, source_len, "r");
d = tmpfile(); d = tmpfile();
if ((!s) || (!d)) if ((!s) || (!d))
goto error; goto out;
if (!lrzip_file_add(lr, s)) if (!lrzip_file_add(lr, s))
goto error; goto out;
lrzip_outfile_set(lr, d); lrzip_outfile_set(lr, d);
if (!lrzip_run(lr)) if (!lrzip_run(lr))
goto error; goto out;
fd = fileno(d); fd = fileno(d);
if (fstat(fd, &st)) if (fstat(fd, &st))
goto error; goto out;
*dest_len = st.st_size; *dest_len = st.st_size;
if (unlikely((i64)fread(dest, sizeof(char), st.st_size, d) != st.st_size)) if (unlikely((i64)fread(dest, sizeof(char), st.st_size, d) != st.st_size))
goto error; goto out;
if (unlikely(ferror(d))) if (unlikely(ferror(d)))
goto error; goto out;
fclose(s); ret = true;
fclose(d);
return true;
error: out:
if (s) fclose(s); if (s) fclose(s);
if (d) fclose(d); if (d) fclose(d);
lrzip_free(lr); lrzip_free(lr);
return false; return ret;
} }