diff --git a/src/tag/Aiff.cxx b/src/tag/Aiff.cxx index 645320ae2..7b18e547b 100644 --- a/src/tag/Aiff.cxx +++ b/src/tag/Aiff.cxx @@ -42,16 +42,22 @@ struct aiff_chunk_header { uint32_t size; }; +gcc_pure +static off_t +GetFileSize(FILE *file) +{ + struct stat st; + return fstat(fileno(file), &st) == 0 + ? st.st_size + : -1; +} + size_t aiff_seek_id3(FILE *file) { /* determine the file size */ - struct stat st; - if (fstat(fileno(file), &st) < 0) { - LogErrno(aiff_domain, "Failed to stat file descriptor"); - return 0; - } + const off_t file_size = GetFileSize(file); /* seek to the beginning and read the AIFF header */ @@ -64,7 +70,8 @@ aiff_seek_id3(FILE *file) size_t size = fread(&header, sizeof(header), 1, file); if (size != 1 || memcmp(header.id, "FORM", 4) != 0 || - FromBE32(header.size) > (uint32_t)st.st_size || + (file_size >= 0 && + FromBE32(header.size) > (uint32_t)file_size) || (memcmp(header.format, "AIFF", 4) != 0 && memcmp(header.format, "AIFC", 4) != 0)) /* not a AIFF file */ diff --git a/src/tag/Riff.cxx b/src/tag/Riff.cxx index 9d79bb564..1b9b46961 100644 --- a/src/tag/Riff.cxx +++ b/src/tag/Riff.cxx @@ -42,16 +42,22 @@ struct riff_chunk_header { uint32_t size; }; +gcc_pure +static off_t +GetFileSize(FILE *file) +{ + struct stat st; + return fstat(fileno(file), &st) == 0 + ? st.st_size + : -1; +} + size_t riff_seek_id3(FILE *file) { /* determine the file size */ - struct stat st; - if (fstat(fileno(file), &st) < 0) { - LogErrno(riff_domain, "Failed to stat file descriptor"); - return 0; - } + const off_t file_size = GetFileSize(file); /* seek to the beginning and read the RIFF header */ @@ -64,7 +70,7 @@ riff_seek_id3(FILE *file) size_t size = fread(&header, sizeof(header), 1, file); if (size != 1 || memcmp(header.id, "RIFF", 4) != 0 || - FromLE32(header.size) > (uint32_t)st.st_size) + (file_size >= 0 && FromLE32(header.size) > (uint32_t)file_size)) /* not a RIFF file */ return 0;