diff options
author | Magnus Holmgren <magnushol@gmail.com> | 2007-10-13 11:21:10 +0000 |
---|---|---|
committer | Magnus Holmgren <magnushol@gmail.com> | 2007-10-13 11:21:10 +0000 |
commit | 5fc117ea4e1aedf820a9787e33f208b489a31407 (patch) | |
tree | 06d86e25af3ca4bdf0bf6a2ec26d20d7de249495 | |
parent | c9bd970ad66ebef13db3d41bbfd466e37e08020c (diff) | |
download | rockbox-5fc117ea4e1aedf820a9787e33f208b489a31407.tar.gz rockbox-5fc117ea4e1aedf820a9787e33f208b489a31407.zip |
Make the FLAC metadata parser a little more robust.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15093 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/metadata/flac.c | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/apps/metadata/flac.c b/apps/metadata/flac.c index 5b3644ede2..f2626d7950 100644 --- a/apps/metadata/flac.c +++ b/apps/metadata/flac.c | |||
@@ -38,6 +38,7 @@ bool get_flac_metadata(int fd, struct mp3entry* id3) | |||
38 | 38 | ||
39 | /* Use the trackname part of the id3 structure as a temporary buffer */ | 39 | /* Use the trackname part of the id3 structure as a temporary buffer */ |
40 | unsigned char* buf = (unsigned char *)id3->path; | 40 | unsigned char* buf = (unsigned char *)id3->path; |
41 | bool last_metadata = false; | ||
41 | bool rc = false; | 42 | bool rc = false; |
42 | 43 | ||
43 | if (!skip_id3v2(fd, id3) || (read(fd, buf, 4) < 4)) | 44 | if (!skip_id3v2(fd, id3) || (read(fd, buf, 4) < 4)) |
@@ -50,24 +51,26 @@ bool get_flac_metadata(int fd, struct mp3entry* id3) | |||
50 | return rc; | 51 | return rc; |
51 | } | 52 | } |
52 | 53 | ||
53 | while (true) | 54 | while (!last_metadata) |
54 | { | 55 | { |
55 | long i; | 56 | unsigned long i; |
57 | int type; | ||
56 | 58 | ||
57 | if (read(fd, buf, 4) < 0) | 59 | if (read(fd, buf, 4) < 0) |
58 | { | 60 | { |
59 | return rc; | 61 | return rc; |
60 | } | 62 | } |
61 | 63 | ||
64 | last_metadata = buf[0] & 0x80; | ||
65 | type = buf[0] & 0x7f; | ||
62 | /* The length of the block */ | 66 | /* The length of the block */ |
63 | i = (buf[1] << 16) | (buf[2] << 8) | buf[3]; | 67 | i = (buf[1] << 16) | (buf[2] << 8) | buf[3]; |
64 | 68 | ||
65 | if ((buf[0] & 0x7f) == 0) /* 0 is the STREAMINFO block */ | 69 | if (type == 0) /* 0 is the STREAMINFO block */ |
66 | { | 70 | { |
67 | unsigned long totalsamples; | 71 | unsigned long totalsamples; |
68 | 72 | ||
69 | /* FIXME: Don't trust the value of i */ | 73 | if (i >= sizeof(id3->path) || read(fd, buf, i) < 0) |
70 | if (read(fd, buf, i) < 0) | ||
71 | { | 74 | { |
72 | return rc; | 75 | return rc; |
73 | } | 76 | } |
@@ -92,7 +95,7 @@ bool get_flac_metadata(int fd, struct mp3entry* id3) | |||
92 | 95 | ||
93 | id3->bitrate = (id3->filesize * 8) / id3->length; | 96 | id3->bitrate = (id3->filesize * 8) / id3->length; |
94 | } | 97 | } |
95 | else if ((buf[0] & 0x7f) == 4) /* 4 is the VORBIS_COMMENT block */ | 98 | else if (type == 4) /* 4 is the VORBIS_COMMENT block */ |
96 | { | 99 | { |
97 | /* The next i bytes of the file contain the VORBIS COMMENTS. */ | 100 | /* The next i bytes of the file contain the VORBIS COMMENTS. */ |
98 | if (!read_vorbis_tags(fd, id3, i)) | 101 | if (!read_vorbis_tags(fd, id3, i)) |
@@ -100,20 +103,12 @@ bool get_flac_metadata(int fd, struct mp3entry* id3) | |||
100 | return rc; | 103 | return rc; |
101 | } | 104 | } |
102 | } | 105 | } |
103 | else | 106 | else if (!last_metadata) |
104 | { | 107 | { |
105 | if (buf[0] & 0x80) | 108 | /* Skip to next metadata block */ |
106 | { | 109 | if (lseek(fd, i, SEEK_CUR) < 0) |
107 | /* If we have reached the last metadata block, abort. */ | ||
108 | break; | ||
109 | } | ||
110 | else | ||
111 | { | 110 | { |
112 | /* Skip to next metadata block */ | 111 | return rc; |
113 | if (lseek(fd, i, SEEK_CUR) < 0) | ||
114 | { | ||
115 | return rc; | ||
116 | } | ||
117 | } | 112 | } |
118 | } | 113 | } |
119 | } | 114 | } |