Skip to content

Commit

Permalink
Prevent file descriptor leak
Browse files Browse the repository at this point in the history
  • Loading branch information
aaaaaa123456789 committed Jan 22, 2022
1 parent d15765a commit e64cad6
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 25 deletions.
2 changes: 2 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Note: releases are listed from latest to oldest.
- Fixed a bug when loading APNG files with reduced frames
- Fixed a bug in the GIF compressor that would generate invalid compressed frame data when a code size increase and
reduction occured at the same time
- Fixed a file descriptor leak that would keep an open `FILE *` if a `PLUM_ERR_FILE_ERROR` error was raised while
reading from a file
- Ensured that the `PLUM_FILENAME`, `PLUM_BUFFER` and `PLUM_CALLBACK` constants are always `size_t` as documented
- Enforced the size limitation on the value returned by a callback when using the `PLUM_CALLBACK` loading/storing mode
- Handled out-of-palette background colors when generating a GIF file, ensuring that they would never cause the
Expand Down
24 changes: 10 additions & 14 deletions src/load.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct plum_image * plum_load_image_limited (const void * restrict buffer, size_
else
update_loaded_palette(context, flags);
done:
if (context -> file) fclose(context -> file);
if (error) *error = context -> status;
struct plum_image * image = context -> image;
if (context -> status) {
Expand Down Expand Up @@ -94,24 +95,19 @@ void prepare_image_buffer_data (struct context * context, const void * restrict
}

void load_file (struct context * context, const char * filename) {
FILE * fp = fopen(filename, "rb");
if (!fp) throw(context, PLUM_ERR_FILE_INACCESSIBLE);
context -> file = fopen(filename, "rb");
if (!context -> file) throw(context, PLUM_ERR_FILE_INACCESSIBLE);
size_t allocated;
char * buffer = resize_read_buffer(context, NULL, &allocated);
size_t size = fread(buffer, 1, allocated, fp);
if (ferror(fp)) {
fclose(fp);
throw(context, PLUM_ERR_FILE_ERROR);
}
while (!feof(fp)) {
size_t size = fread(buffer, 1, allocated, context -> file);
if (ferror(context -> file)) throw(context, PLUM_ERR_FILE_ERROR);
while (!feof(context -> file)) {
if ((allocated - size) < 0x4000) buffer = resize_read_buffer(context, buffer, &allocated);
size += fread(buffer + size, 1, 0x4000, fp);
if (ferror(fp)) {
fclose(fp);
throw(context, PLUM_ERR_FILE_ERROR);
}
size += fread(buffer + size, 1, 0x4000, context -> file);
if (ferror(context -> file)) throw(context, PLUM_ERR_FILE_ERROR);
}
fclose(fp);
fclose(context -> file);
context -> file = NULL;
context -> data = ctxrealloc(context, buffer, size);
context -> size = size;
}
Expand Down
20 changes: 9 additions & 11 deletions src/store.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,32 +41,30 @@ size_t plum_store_image (const struct plum_image * image, void * restrict buffer
}
result = output_size;
done:
if (context -> file) fclose(context -> file);
if (error) *error = context -> status;
destroy_allocator_list(context -> allocator);
return result;
}

void write_generated_image_data_to_file (struct context * context, const char * filename) {
FILE * fp = fopen(filename, "wb");
if (!fp) throw(context, PLUM_ERR_FILE_INACCESSIBLE);
context -> file = fopen(filename, "wb");
if (!context -> file) throw(context, PLUM_ERR_FILE_INACCESSIBLE);
const struct data_node * node;
for (node = context -> output; node -> previous; node = node -> previous);
while (node) {
const unsigned char * data = node -> data;
size_t size = node -> size;
while (size) {
unsigned count = fwrite(data, 1, (size > 0x4000) ? 0x4000 : size, fp);
if (count) {
data += count;
size -= count;
} else {
fclose(fp);
throw(context, PLUM_ERR_FILE_ERROR);
}
unsigned count = fwrite(data, 1, (size > 0x4000) ? 0x4000 : size, context -> file);
if (ferror(context -> file) || !count) throw(context, PLUM_ERR_FILE_ERROR);
data += count;
size -= count;
}
node = node -> next;
}
fclose(fp);
fclose(context -> file);
context -> file = NULL;
}

void write_generated_image_data_to_callback (struct context * context, const struct plum_callback * callback) {
Expand Down
2 changes: 2 additions & 0 deletions src/struct.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <setjmp.h>
Expand Down Expand Up @@ -36,6 +37,7 @@ struct context {
struct plum_image * image;
const struct plum_image * source;
};
FILE * file;
jmp_buf target;
};

Expand Down

0 comments on commit e64cad6

Please sign in to comment.