diff options
author | William Wilgus <wilgus.william@gmail.com> | 2021-08-10 16:47:52 -0400 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2021-08-11 01:36:32 +0000 |
commit | c9e95580445530c5b6d2ca31d04f07bd61ad843f (patch) | |
tree | 63a0d79e4e8d988e1526d8c9c6e4015db077cdcf | |
parent | 77a98ada1255ecf38b7f59924bb13673a5fd4121 (diff) | |
download | rockbox-c9e95580445530c5b6d2ca31d04f07bd61ad843f.tar.gz rockbox-c9e95580445530c5b6d2ca31d04f07bd61ad843f.zip |
metadata/mp4.c check for read errors skip buffer appropriately
WIP
Change-Id: I770f0d911f7d9826e89d886892ff3913661a8151
-rw-r--r-- | lib/rbcodec/metadata/mp4.c | 108 |
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 @@ | |||
85 | static unsigned long read_mp4_tag(int fd, unsigned int size_left, char* buffer, | 85 | static 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, |