From 00dfdc8b5c941287341b9dbc9e65a0d3c4fd4aa4 Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 15 Jun 2023 14:32:33 +0600 Subject: [PATCH 1/2] Error check qoi_write() more strictly simply checking the return value of fwrite() wouldn't be enough since stdio is typically buffered. and so force a flush and check for errors via ferror(). --- qoi.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qoi.h b/qoi.h index 6734ac46..eb01232a 100644 --- a/qoi.h +++ b/qoi.h @@ -594,7 +594,7 @@ void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels) { int qoi_write(const char *filename, const void *data, const qoi_desc *desc) { FILE *f = fopen(filename, "wb"); - int size; + int size, err; void *encoded; if (!f) { @@ -608,10 +608,12 @@ int qoi_write(const char *filename, const void *data, const qoi_desc *desc) { } fwrite(encoded, 1, size, f); + fflush(f); + err = ferror(f); fclose(f); QOI_FREE(encoded); - return size; + return err ? 0 : size; } void *qoi_read(const char *filename, qoi_desc *desc, int channels) { From 36190eb07dc5d85f408d998d1884eb69573adf68 Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 15 Jun 2023 14:43:24 +0600 Subject: [PATCH 2/2] Error check qoi_read() more strictly fseek is not guaranteed to succeed and can fail, e.g when trying to seek a pipe. the first fseek() is not error checked since if it failed, ftell would return 0. also check for fread errors too before calling qoi_decode(). --- qoi.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/qoi.h b/qoi.h index eb01232a..f2800b0c 100644 --- a/qoi.h +++ b/qoi.h @@ -627,11 +627,10 @@ void *qoi_read(const char *filename, qoi_desc *desc, int channels) { fseek(f, 0, SEEK_END); size = ftell(f); - if (size <= 0) { + if (size <= 0 || fseek(f, 0, SEEK_SET) != 0) { fclose(f); return NULL; } - fseek(f, 0, SEEK_SET); data = QOI_MALLOC(size); if (!data) { @@ -641,8 +640,7 @@ void *qoi_read(const char *filename, qoi_desc *desc, int channels) { bytes_read = fread(data, 1, size, f); fclose(f); - - pixels = qoi_decode(data, bytes_read, desc, channels); + pixels = (bytes_read != size) ? NULL : qoi_decode(data, bytes_read, desc, channels); QOI_FREE(data); return pixels; }