Cleaned up double free, 'fixed' random decompress segfault

This commit is contained in:
Pentium44 2021-04-10 19:08:05 -07:00
parent b99bdebaa8
commit d8ae96e2ed
3 changed files with 37 additions and 26 deletions

View File

@ -44,8 +44,11 @@ uint32_t lz77_compress (uint8_t *uncompressed_text, uint32_t uncompressed_size,
look_behind = coding_pos - temp_pointer_pos; look_behind = coding_pos - temp_pointer_pos;
look_ahead = coding_pos; look_ahead = coding_pos;
for(temp_pointer_length = 0; uncompressed_text[look_ahead++] == uncompressed_text[look_behind++]; ++temp_pointer_length) for(temp_pointer_length = 0; uncompressed_text[look_ahead++] == uncompressed_text[look_behind++]; ++temp_pointer_length)
{
if(temp_pointer_length == pointer_length_max) if(temp_pointer_length == pointer_length_max)
break; break;
}
if(temp_pointer_length > pointer_length) if(temp_pointer_length > pointer_length)
{ {
pointer_pos = temp_pointer_pos; pointer_pos = temp_pointer_pos;
@ -121,30 +124,31 @@ uint32_t ss_compress (const char *filename_in, char *filename_out, uint8_t point
if(in == NULL) if(in == NULL)
return 0; return 0;
uncompressed_size = fsize(in); uncompressed_size = fsize(in);
uncompressed_text = malloc(uncompressed_size); uncompressed_text = malloc(uncompressed_size + 20);
// +20 for uncompressed data size sway in algorithm
if((uncompressed_size != fread(uncompressed_text, 1, uncompressed_size, in))) if((uncompressed_size != fread(uncompressed_text, 1, uncompressed_size, in)))
{ {
free(uncompressed_text); my_free(uncompressed_text);
return 0; return 0;
} }
fclose(in); fclose(in);
compressed_text = malloc(uncompressed_size * 2); compressed_text = malloc((int)(uncompressed_size * 1.25));
// * 2 for uncompressed size climb on first compress pass
compressed_size = lz77_compress(uncompressed_text, uncompressed_size, compressed_text, pointer_length_width); compressed_size = lz77_compress(uncompressed_text, uncompressed_size, compressed_text, pointer_length_width);
out = fopen(filename_out, "wb"); out = fopen(filename_out, "wb");
if(out == NULL) if(out == NULL)
{ {
free(uncompressed_text); my_free(uncompressed_text);
free(compressed_text); my_free(compressed_text);
return 0; return 0;
} }
if((compressed_size != fwrite(compressed_text, 1, compressed_size, out))) if((compressed_size != fwrite(compressed_text, 1, compressed_size, out)))
{ {
free(uncompressed_text); my_free(uncompressed_text);
free(compressed_text); my_free(compressed_text);
fclose(out); fclose(out);
return 0; return 0;
} }
@ -203,8 +207,9 @@ uint32_t ss_decompress
// Compressed size // Compressed size
comp_size = (int) fsize (ifp); comp_size = (int) fsize (ifp);
// DM: Compressed data // DM: Compressed data
dm_comp = (uint8_t *) malloc (comp_size); dm_comp = (uint8_t *) malloc (comp_size + 10);
// Add some extra memory at the end of malloc comp_size
// Saves dirty archive size sway, WIP
if (dm_comp == NULL) // Error? if (dm_comp == NULL) // Error?
{ // Yes - Error exit { // Yes - Error exit
fprintf (stderr, fprintf (stderr,
@ -234,8 +239,8 @@ uint32_t ss_decompress
// Set up decompressed-data buffer. // Set up decompressed-data buffer.
orig_size = (int) *((uint32_t *) dm_comp); orig_size = (int) *((uint32_t *) dm_comp);
dm_deco = (uint8_t *) malloc (orig_size); dm_deco = (uint8_t *) malloc (orig_size + 20);
// +20 to cover byte sway, dirty trick for mem leak
if (dm_comp == NULL) // Error? if (dm_comp == NULL) // Error?
{ // Yes { // Yes
my_free (dm_comp); // Release DM my_free (dm_comp); // Release DM

View File

@ -162,9 +162,11 @@ char *process_line(char *line)
// perform operation // perform operation
if(tar_extract(fd, archive, 0, NULL, '1') < 0) { // extract entries if(tar_extract(fd, archive, 0, NULL, '1') < 0) { // extract entries
syn_warn("ss:warn:decompress, error occured"); syn_warn("ss:warn:decompress, error occured");
return NULL;
} }
tar_free(archive); tar_free(archive);
close(fd); // don't bother checking for fd < 0 close(fd); // don't bother checking for fd < 0
remove(filedecout); remove(filedecout);

View File

@ -8,7 +8,6 @@
#define ERROR(fmt, ...) fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__); return -1; #define ERROR(fmt, ...) fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__); return -1;
// capture errno when erroring // capture errno when erroring
#define RC_ERROR(fmt, ...) const int rc = errno; ERROR(fmt, ##__VA_ARGS__); return -1; #define RC_ERROR(fmt, ...) const int rc = errno; ERROR(fmt, ##__VA_ARGS__); return -1;
#define WRITE_ERROR(fmt, ...) { ERROR(fmt, ##__VA_ARGS__); tar_free(*archive); *archive = NULL; return -1; }
#define EXIST_ERROR(fmt, ...) const int rc = errno; if (rc != EEXIST) { ERROR(fmt, ##__VA_ARGS__); return -1; } #define EXIST_ERROR(fmt, ...) const int rc = errno; if (rc != EEXIST) { ERROR(fmt, ##__VA_ARGS__); return -1; }
// force read() to complete // force read() to complete
@ -134,7 +133,7 @@ int tar_write(const int fd, struct tar_t ** archive, const size_t filecount, con
// write entries first // write entries first
if (write_entries(fd, tar, archive, filecount, files, &offset, verbosity) < 0){ if (write_entries(fd, tar, archive, filecount, files, &offset, verbosity) < 0){
WRITE_ERROR("Failed to write entries"); tar_free(*archive);
} }
// write ending data // write ending data
@ -151,10 +150,15 @@ int tar_write(const int fd, struct tar_t ** archive, const size_t filecount, con
return offset; return offset;
} }
void tar_free(struct tar_t * archive){ void tar_free (struct tar_t *archive)
{
while (archive){ while (archive){
struct tar_t * next = archive -> next; struct tar_t * next = archive -> next;
if(archive != (void *) 0)
{
free(archive); free(archive);
archive = NULL;
}
archive = next; archive = next;
} }
} }
@ -841,7 +845,7 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c
// stat file // stat file
if (format_tar_data(*tar, files[i], verbosity) < 0){ if (format_tar_data(*tar, files[i], verbosity) < 0){
WRITE_ERROR("Failed to stat %s", files[i]); tar_free(*tar);
} }
(*tar) -> begin = *offset; (*tar) -> begin = *offset;
@ -864,13 +868,13 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c
// write metadata to (*tar) file // write metadata to (*tar) file
if (write_size(fd, (*tar) -> block, 512) != 512){ if (write_size(fd, (*tar) -> block, 512) != 512){
WRITE_ERROR("Failed to write metadata to archive"); tar_free(*tar);
} }
// go through directory // go through directory
DIR * d = opendir(parent); DIR * d = opendir(parent);
if (!d){ if (!d){
WRITE_ERROR("Cannot open directory %s", parent); tar_free(*tar);
} }
struct dirent * dir; struct dirent * dir;
@ -883,7 +887,7 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c
// recursively write each subdirectory // recursively write each subdirectory
if (write_entries(fd, &((*tar) -> next), head, 1, (const char **) &path, offset, verbosity) < 0){ if (write_entries(fd, &((*tar) -> next), head, 1, (const char **) &path, offset, verbosity) < 0){
WRITE_ERROR("Recurse error"); tar_free(*tar);
} }
// go to end of new data // go to end of new data
@ -926,7 +930,7 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c
// write metadata to (*tar) file // write metadata to (*tar) file
if (write_size(fd, (*tar) -> block, 512) != 512){ if (write_size(fd, (*tar) -> block, 512) != 512){
WRITE_ERROR("Failed to write metadata to archive"); tar_free(*tar);
} }
if (((*tar) -> type == REGULAR) || ((*tar) -> type == NORMAL) || ((*tar) -> type == CONTIGUOUS)){ if (((*tar) -> type == REGULAR) || ((*tar) -> type == NORMAL) || ((*tar) -> type == CONTIGUOUS)){
@ -934,7 +938,7 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c
if (!tarred){ if (!tarred){
int f = open((*tar) -> name, O_RDONLY); int f = open((*tar) -> name, O_RDONLY);
if (f < 0){ if (f < 0){
WRITE_ERROR("Could not open %s", files[i]); tar_free(*tar);
} }
int r = 0; int r = 0;
@ -955,7 +959,7 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c
if (pad != 512){ if (pad != 512){
for(unsigned int j = 0; j < pad; j++){ for(unsigned int j = 0; j < pad; j++){
if (write_size(fd, "\0", 1) != 1){ if (write_size(fd, "\0", 1) != 1){
WRITE_ERROR("Could not write padding data"); tar_free(*tar);
} }
} }
*offset += pad; *offset += pad;