1
0
Fork 0
forked from len0rd/rockbox

metadata/mp4.c check for read errors skip buffer appropriately

WIP

Change-Id: I770f0d911f7d9826e89d886892ff3913661a8151
This commit is contained in:
William Wilgus 2021-08-10 16:47:52 -04:00 committed by William Wilgus
parent 77a98ada12
commit c9e9558044

View file

@ -85,31 +85,38 @@
static unsigned long read_mp4_tag(int fd, unsigned int size_left, char* buffer, static unsigned long read_mp4_tag(int fd, unsigned int size_left, char* buffer,
unsigned int buffer_left) unsigned int buffer_left)
{ {
unsigned int bytes_read = 0; unsigned long bytes_read = 0;
ssize_t rd_ret = 0;
if (buffer_left == 0) ssize_t bytes_req;
{ #define MP4_TAG_HEADER_SIZE 16
lseek(fd, size_left, SEEK_CUR); /* Skip everything */
}
else if (size_left >= MP4_TAG_HEADER_SIZE)
{ {
/* Skip the data tag header - maybe we should parse it properly? */ /* Skip the data tag header - maybe we should parse it properly? */
lseek(fd, 16, SEEK_CUR); lseek(fd, MP4_TAG_HEADER_SIZE, SEEK_CUR);
size_left -= 16; size_left -= MP4_TAG_HEADER_SIZE;
if (size_left > buffer_left) if (size_left > buffer_left)
{ bytes_req = buffer_left;
read(fd, buffer, buffer_left); else
lseek(fd, size_left - buffer_left, SEEK_CUR); bytes_req = size_left;
bytes_read = buffer_left;
} rd_ret = read(fd, buffer, bytes_req);
if (rd_ret == bytes_req)
bytes_read = bytes_req;
else else
{ {
read(fd, buffer, size_left); /* read less than expected or an error from read() */
bytes_read = size_left; logf("Error %d, read_mp4_tag", rd_ret);
if (rd_ret < 0)
rd_ret = 0; /* Skip everything */
} }
} }
if (size_left > (unsigned int) rd_ret)
lseek(fd, size_left - rd_ret, SEEK_CUR);
return bytes_read; return bytes_read;
} }
@ -437,10 +444,11 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
case MP4_gnre: case MP4_gnre:
{ {
unsigned short genre; unsigned short genre = USHRT_MAX; /*invalid genre*/
unsigned long rd_ret;
read_mp4_tag(fd, size, (char*) &genre, sizeof(genre)); rd_ret = read_mp4_tag(fd, size, (char*) &genre, sizeof(genre));
id3->genre_string = id3_get_num_genre(betoh16(genre) - 1); if (rd_ret == sizeof(genre))
id3->genre_string = id3_get_num_genre(betoh16(genre) - 1);
} }
break; break;
@ -452,18 +460,18 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
case MP4_disk: case MP4_disk:
{ {
unsigned short n[2]; unsigned short n[2];
id3->discnum = 0;
read_mp4_tag(fd, size, (char*) &n, sizeof(n)); if (read_mp4_tag(fd, size, (char*) &n, sizeof(n)) == sizeof(n))
id3->discnum = betoh16(n[1]); id3->discnum = betoh16(n[1]);
} }
break; break;
case MP4_trkn: case MP4_trkn:
{ {
unsigned short n[2]; unsigned short n[2];
id3->tracknum = 0;
read_mp4_tag(fd, size, (char*) &n, sizeof(n)); if (read_mp4_tag(fd, size, (char*) &n, sizeof(n)) == sizeof(n))
id3->tracknum = betoh16(n[1]); id3->tracknum = betoh16(n[1]);
} }
break; break;
@ -471,23 +479,26 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
case MP4_covr: case MP4_covr:
{ {
int pos = lseek(fd, 0, SEEK_CUR) + 16; int pos = lseek(fd, 0, SEEK_CUR) + 16;
read_mp4_tag(fd, size, buffer, 8);
id3->albumart.type = AA_TYPE_UNKNOWN; id3->albumart.type = AA_TYPE_UNKNOWN;
if (memcmp(buffer, "\xff\xd8\xff\xe0", 4) == 0)
{
id3->albumart.type = AA_TYPE_JPG;
}
else if (memcmp(buffer, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) == 0)
{
id3->albumart.type = AA_TYPE_PNG;
}
if (id3->albumart.type != AA_TYPE_UNKNOWN) if (read_mp4_tag(fd, size, buffer, 8) >= 4)
{ {
id3->albumart.pos = pos;
id3->albumart.size = size - 16; if (memcmp(buffer, "\xff\xd8\xff\xe0", 4) == 0)
id3->has_embedded_albumart = true; {
id3->albumart.type = AA_TYPE_JPG;
}
else if (memcmp(buffer, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) == 0)
{
id3->albumart.type = AA_TYPE_PNG;
}
if (id3->albumart.type != AA_TYPE_UNKNOWN)
{
id3->albumart.pos = pos;
id3->albumart.size = size - 16;
id3->has_embedded_albumart = true;
}
} }
} }
break; break;
@ -497,7 +508,7 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
{ {
char tag_name[TAG_NAME_LENGTH]; char tag_name[TAG_NAME_LENGTH];
uint32_t sub_size; uint32_t sub_size;
ssize_t rd_ret;
/* "mean" atom */ /* "mean" atom */
read_uint32be(fd, &sub_size); read_uint32be(fd, &sub_size);
size -= sub_size; size -= sub_size;
@ -510,16 +521,19 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
if (sub_size > sizeof(tag_name) - 1) if (sub_size > sizeof(tag_name) - 1)
{ {
read(fd, tag_name, sizeof(tag_name) - 1); rd_ret = read(fd, tag_name, sizeof(tag_name) - 1);
lseek(fd, sub_size - (sizeof(tag_name) - 1), SEEK_CUR); lseek(fd, sub_size - (sizeof(tag_name) - 1), SEEK_CUR);
tag_name[sizeof(tag_name) - 1] = 0; sub_size = sizeof(tag_name) - 1;
} }
else else
{ {
read(fd, tag_name, sub_size); rd_ret = read(fd, tag_name, sub_size);
tag_name[sub_size] = 0;
} }
if (rd_ret != (ssize_t)sub_size)
rd_ret = 0;
tag_name[rd_ret] = 0;
if ((strcasecmp(tag_name, "composer") == 0) && !cwrt) if ((strcasecmp(tag_name, "composer") == 0) && !cwrt)
{ {
read_mp4_tag_string(fd, size, &buffer, &buffer_left, read_mp4_tag_string(fd, size, &buffer, &buffer_left,