summaryrefslogtreecommitdiff
path: root/lib/rbcodec
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2021-08-10 16:47:52 -0400
committerWilliam Wilgus <me.theuser@yahoo.com>2021-08-11 01:36:32 +0000
commitc9e95580445530c5b6d2ca31d04f07bd61ad843f (patch)
tree63a0d79e4e8d988e1526d8c9c6e4015db077cdcf /lib/rbcodec
parent77a98ada1255ecf38b7f59924bb13673a5fd4121 (diff)
downloadrockbox-c9e95580445530c5b6d2ca31d04f07bd61ad843f.tar.gz
rockbox-c9e95580445530c5b6d2ca31d04f07bd61ad843f.zip
metadata/mp4.c check for read errors skip buffer appropriately
WIP Change-Id: I770f0d911f7d9826e89d886892ff3913661a8151
Diffstat (limited to 'lib/rbcodec')
-rw-r--r--lib/rbcodec/metadata/mp4.c108
1 files changed, 61 insertions, 47 deletions
diff --git a/lib/rbcodec/metadata/mp4.c b/lib/rbcodec/metadata/mp4.c
index c20877b893..e79af3bd7b 100644
--- a/lib/rbcodec/metadata/mp4.c
+++ b/lib/rbcodec/metadata/mp4.c
@@ -85,31 +85,38 @@
85static unsigned long read_mp4_tag(int fd, unsigned int size_left, char* buffer, 85static unsigned long read_mp4_tag(int fd, unsigned int size_left, char* buffer,
86 unsigned int buffer_left) 86 unsigned int buffer_left)
87{ 87{
88 unsigned int bytes_read = 0; 88 unsigned long bytes_read = 0;
89 89 ssize_t rd_ret = 0;
90 if (buffer_left == 0) 90 ssize_t bytes_req;
91 { 91 #define MP4_TAG_HEADER_SIZE 16
92 lseek(fd, size_left, SEEK_CUR); /* Skip everything */ 92
93 } 93
94 else 94 if (size_left >= MP4_TAG_HEADER_SIZE)
95 { 95 {
96 /* Skip the data tag header - maybe we should parse it properly? */ 96 /* Skip the data tag header - maybe we should parse it properly? */
97 lseek(fd, 16, SEEK_CUR); 97 lseek(fd, MP4_TAG_HEADER_SIZE, SEEK_CUR);
98 size_left -= 16; 98 size_left -= MP4_TAG_HEADER_SIZE;
99 99
100 if (size_left > buffer_left) 100 if (size_left > buffer_left)
101 { 101 bytes_req = buffer_left;
102 read(fd, buffer, buffer_left); 102 else
103 lseek(fd, size_left - buffer_left, SEEK_CUR); 103 bytes_req = size_left;
104 bytes_read = buffer_left; 104
105 } 105 rd_ret = read(fd, buffer, bytes_req);
106 if (rd_ret == bytes_req)
107 bytes_read = bytes_req;
106 else 108 else
107 { 109 {
108 read(fd, buffer, size_left); 110 /* read less than expected or an error from read() */
109 bytes_read = size_left; 111 logf("Error %d, read_mp4_tag", rd_ret);
112 if (rd_ret < 0)
113 rd_ret = 0; /* Skip everything */
110 } 114 }
111 } 115 }
112 116 if (size_left > (unsigned int) rd_ret)
117 lseek(fd, size_left - rd_ret, SEEK_CUR);
118
119
113 return bytes_read; 120 return bytes_read;
114} 121}
115 122
@@ -437,10 +444,11 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
437 444
438 case MP4_gnre: 445 case MP4_gnre:
439 { 446 {
440 unsigned short genre; 447 unsigned short genre = USHRT_MAX; /*invalid genre*/
441 448 unsigned long rd_ret;
442 read_mp4_tag(fd, size, (char*) &genre, sizeof(genre)); 449 rd_ret = read_mp4_tag(fd, size, (char*) &genre, sizeof(genre));
443 id3->genre_string = id3_get_num_genre(betoh16(genre) - 1); 450 if (rd_ret == sizeof(genre))
451 id3->genre_string = id3_get_num_genre(betoh16(genre) - 1);
444 } 452 }
445 break; 453 break;
446 454
@@ -452,18 +460,18 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
452 case MP4_disk: 460 case MP4_disk:
453 { 461 {
454 unsigned short n[2]; 462 unsigned short n[2];
455 463 id3->discnum = 0;
456 read_mp4_tag(fd, size, (char*) &n, sizeof(n)); 464 if (read_mp4_tag(fd, size, (char*) &n, sizeof(n)) == sizeof(n))
457 id3->discnum = betoh16(n[1]); 465 id3->discnum = betoh16(n[1]);
458 } 466 }
459 break; 467 break;
460 468
461 case MP4_trkn: 469 case MP4_trkn:
462 { 470 {
463 unsigned short n[2]; 471 unsigned short n[2];
464 472 id3->tracknum = 0;
465 read_mp4_tag(fd, size, (char*) &n, sizeof(n)); 473 if (read_mp4_tag(fd, size, (char*) &n, sizeof(n)) == sizeof(n))
466 id3->tracknum = betoh16(n[1]); 474 id3->tracknum = betoh16(n[1]);
467 } 475 }
468 break; 476 break;
469 477
@@ -471,23 +479,26 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
471 case MP4_covr: 479 case MP4_covr:
472 { 480 {
473 int pos = lseek(fd, 0, SEEK_CUR) + 16; 481 int pos = lseek(fd, 0, SEEK_CUR) + 16;
474
475 read_mp4_tag(fd, size, buffer, 8);
476 id3->albumart.type = AA_TYPE_UNKNOWN; 482 id3->albumart.type = AA_TYPE_UNKNOWN;
477 if (memcmp(buffer, "\xff\xd8\xff\xe0", 4) == 0)
478 {
479 id3->albumart.type = AA_TYPE_JPG;
480 }
481 else if (memcmp(buffer, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) == 0)
482 {
483 id3->albumart.type = AA_TYPE_PNG;
484 }
485 483
486 if (id3->albumart.type != AA_TYPE_UNKNOWN) 484 if (read_mp4_tag(fd, size, buffer, 8) >= 4)
487 { 485 {
488 id3->albumart.pos = pos; 486
489 id3->albumart.size = size - 16; 487 if (memcmp(buffer, "\xff\xd8\xff\xe0", 4) == 0)
490 id3->has_embedded_albumart = true; 488 {
489 id3->albumart.type = AA_TYPE_JPG;
490 }
491 else if (memcmp(buffer, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) == 0)
492 {
493 id3->albumart.type = AA_TYPE_PNG;
494 }
495
496 if (id3->albumart.type != AA_TYPE_UNKNOWN)
497 {
498 id3->albumart.pos = pos;
499 id3->albumart.size = size - 16;
500 id3->has_embedded_albumart = true;
501 }
491 } 502 }
492 } 503 }
493 break; 504 break;
@@ -497,7 +508,7 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
497 { 508 {
498 char tag_name[TAG_NAME_LENGTH]; 509 char tag_name[TAG_NAME_LENGTH];
499 uint32_t sub_size; 510 uint32_t sub_size;
500 511 ssize_t rd_ret;
501 /* "mean" atom */ 512 /* "mean" atom */
502 read_uint32be(fd, &sub_size); 513 read_uint32be(fd, &sub_size);
503 size -= sub_size; 514 size -= sub_size;
@@ -510,16 +521,19 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
510 521
511 if (sub_size > sizeof(tag_name) - 1) 522 if (sub_size > sizeof(tag_name) - 1)
512 { 523 {
513 read(fd, tag_name, sizeof(tag_name) - 1); 524 rd_ret = read(fd, tag_name, sizeof(tag_name) - 1);
514 lseek(fd, sub_size - (sizeof(tag_name) - 1), SEEK_CUR); 525 lseek(fd, sub_size - (sizeof(tag_name) - 1), SEEK_CUR);
515 tag_name[sizeof(tag_name) - 1] = 0; 526 sub_size = sizeof(tag_name) - 1;
516 } 527 }
517 else 528 else
518 { 529 {
519 read(fd, tag_name, sub_size); 530 rd_ret = read(fd, tag_name, sub_size);
520 tag_name[sub_size] = 0;
521 } 531 }
522 532 if (rd_ret != (ssize_t)sub_size)
533 rd_ret = 0;
534 tag_name[rd_ret] = 0;
535
536
523 if ((strcasecmp(tag_name, "composer") == 0) && !cwrt) 537 if ((strcasecmp(tag_name, "composer") == 0) && !cwrt)
524 { 538 {
525 read_mp4_tag_string(fd, size, &buffer, &buffer_left, 539 read_mp4_tag_string(fd, size, &buffer, &buffer_left,