FS13094: Fix a divide-by-zero crash parsing zero-length WMA/ASF files

Change-Id: I2e90692327c69c4467a586b23b877c596b8d2c40
This commit is contained in:
Solomon Peachy 2021-05-12 18:22:06 -04:00
parent 84a3cbe24d
commit 942b1dd072

View file

@ -274,13 +274,13 @@ static int asf_parse_header(int fd, struct mp3entry* id3,
} }
fileprop = 1; fileprop = 1;
/* Get the number of logical packets - uint64_t at offset 32 /* Get the number of logical packets - uint64_t at offset 32
* (little endian byte order) */ * (little endian byte order) */
lseek(fd, 32, SEEK_CUR); lseek(fd, 32, SEEK_CUR);
read_uint64le(fd, &wfx->numpackets); read_uint64le(fd, &wfx->numpackets);
/*DEBUGF("read packets: %llx %lld\n", wfx->numpackets, wfx->numpackets);*/ /*DEBUGF("read packets: %llx %lld\n", wfx->numpackets, wfx->numpackets);*/
/* Now get the play duration - uint64_t at offset 40 */ /* Now get the play duration - uint64_t at offset 40 */
read_uint64le(fd, &play_duration); read_uint64le(fd, &play_duration);
id3->length = play_duration / 10000; id3->length = play_duration / 10000;
@ -338,7 +338,7 @@ static int asf_parse_header(int fd, struct mp3entry* id3,
read_uint16le(fd, &wfx->datalen); read_uint16le(fd, &wfx->datalen);
/*sanity check the included bitrate by comparing to file size and length*/ /*sanity check the included bitrate by comparing to file size and length*/
unsigned int estimated_bitrate = (wfx->packet_size*wfx->numpackets)/id3->length*8000; unsigned int estimated_bitrate = id3->length ? (wfx->packet_size*wfx->numpackets)/id3->length*8000 : 0;
/*in theory we could just use the estimated bitrate always, /*in theory we could just use the estimated bitrate always,
but its safer to underestimate*/ but its safer to underestimate*/
@ -484,22 +484,22 @@ static int asf_parse_header(int fd, struct mp3entry* id3,
} else if (!strcmp("WM/Picture", utf8buf)) { } else if (!strcmp("WM/Picture", utf8buf)) {
uint32_t datalength, strlength; uint32_t datalength, strlength;
/* Expected is either "01 00 xx xx 03 yy yy yy yy" or /* Expected is either "01 00 xx xx 03 yy yy yy yy" or
* "03 yy yy yy yy". xx is the size of the WM/Picture * "03 yy yy yy yy". xx is the size of the WM/Picture
* container in bytes. yy equals the raw data length of * container in bytes. yy equals the raw data length of
* the embedded image. */ * the embedded image. */
lseek(fd, -4, SEEK_CUR); lseek(fd, -4, SEEK_CUR);
read(fd, &type, 1); read(fd, &type, 1);
if (type == 1) { if (type == 1) {
lseek(fd, 3, SEEK_CUR); lseek(fd, 3, SEEK_CUR);
read(fd, &type, 1); read(fd, &type, 1);
/* In case the parsing will fail in the next step we /* In case the parsing will fail in the next step we
* might at least be able to skip the whole section. */ * might at least be able to skip the whole section. */
datalength = length - 1; datalength = length - 1;
} }
if (type == 3) { if (type == 3) {
/* Read the raw data length of the embedded image. */ /* Read the raw data length of the embedded image. */
read_uint32le(fd, &datalength); read_uint32le(fd, &datalength);
/* Reset utf8 buffer */ /* Reset utf8 buffer */
utf8 = utf8buf; utf8 = utf8buf;
utf8length = 512; utf8length = 512;
@ -528,7 +528,7 @@ static int asf_parse_header(int fd, struct mp3entry* id3,
id3->has_embedded_albumart = true; id3->has_embedded_albumart = true;
} }
} }
lseek(fd, datalength, SEEK_CUR); lseek(fd, datalength, SEEK_CUR);
#endif #endif
} else { } else {