diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2002-10-28 23:00:57 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2002-10-28 23:00:57 +0000 |
commit | be8ae1c0e2bfb50fce5211b55cd0f13661002a5d (patch) | |
tree | dfe7d216869026a07cb94867e1ad3e4d704c35c7 /firmware/id3.c | |
parent | 8857d47b5ad87f2e6aa47797aa2f5dc4d4e0f672 (diff) | |
download | rockbox-be8ae1c0e2bfb50fce5211b55cd0f13661002a5d.tar.gz rockbox-be8ae1c0e2bfb50fce5211b55cd0f13661002a5d.zip |
Now reads the tags frame by frame, to avoid missing frames when there are large blobs in the tag. This fixes bug #623510.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2768 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/id3.c')
-rw-r--r-- | firmware/id3.c | 133 |
1 files changed, 58 insertions, 75 deletions
diff --git a/firmware/id3.c b/firmware/id3.c index e0e3ca1abf..e59618e234 100644 --- a/firmware/id3.c +++ b/firmware/id3.c | |||
@@ -232,38 +232,28 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
232 | { | 232 | { |
233 | int minframesize; | 233 | int minframesize; |
234 | int size; | 234 | int size; |
235 | int readsize = 0, headerlen; | 235 | int bufferpos = 0, totframelen, framelen; |
236 | char *title = NULL; | ||
237 | char *artist = NULL; | ||
238 | char *album = NULL; | ||
239 | char *tracknum = NULL; | ||
240 | char header[10]; | 236 | char header[10]; |
241 | unsigned short int version; | 237 | unsigned short int version; |
242 | int titlen=0, artistn=0, albumn=0, tracknumn=0; | ||
243 | char *buffer = entry->id3v2buf; | 238 | char *buffer = entry->id3v2buf; |
239 | char *tracknum = NULL; | ||
240 | int bytesread = 0; | ||
241 | int buffersize = sizeof(entry->id3v2buf); | ||
244 | 242 | ||
245 | /* 10 = headerlength */ | 243 | /* Bail out if the tag is shorter than 10 bytes */ |
246 | if(entry->id3v2len < 10) | 244 | if(entry->id3v2len < 10) |
247 | return; | 245 | return; |
248 | 246 | ||
249 | /* Check version */ | 247 | /* Read the ID3 tag version from the header */ |
250 | lseek(fd, 0, SEEK_SET); | 248 | lseek(fd, 0, SEEK_SET); |
251 | if(10 != read(fd, header, 10)) | 249 | if(10 != read(fd, header, 10)) |
252 | return; | 250 | return; |
253 | 251 | ||
254 | version = (unsigned short int)header[3]; | 252 | version = (unsigned short int)header[3]; |
255 | 253 | ||
256 | /* Read all frames in the tag */ | 254 | /* Get the total ID3 tag size */ |
257 | size = entry->id3v2len - 10; | 255 | size = entry->id3v2len - 10; |
258 | 256 | ||
259 | if(size >= (int)sizeof(entry->id3v2buf)) | ||
260 | size = sizeof(entry->id3v2buf)-1; | ||
261 | |||
262 | if(size != read(fd, buffer, size)) | ||
263 | return; | ||
264 | |||
265 | *(buffer + size) = '\0'; | ||
266 | |||
267 | /* Set minimum frame size according to ID3v2 version */ | 257 | /* Set minimum frame size according to ID3v2 version */ |
268 | if(version > 2) | 258 | if(version > 2) |
269 | minframesize = 12; | 259 | minframesize = 12; |
@@ -274,86 +264,79 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
274 | * We must have at least minframesize bytes left for the | 264 | * We must have at least minframesize bytes left for the |
275 | * remaining frames to be interesting | 265 | * remaining frames to be interesting |
276 | */ | 266 | */ |
277 | while(size - readsize > minframesize) { | 267 | while(size > minframesize) { |
278 | |||
279 | /* Read frame header and check length */ | 268 | /* Read frame header and check length */ |
280 | if(version > 2) { | 269 | if(version > 2) { |
281 | memcpy(header, (buffer + readsize), 10); | 270 | if(10 != read(fd, header, 10)) |
282 | readsize += 10; | 271 | return; |
272 | /* Adjust for the 10 bytes we read */ | ||
273 | size -= 10; | ||
274 | |||
283 | if (version > 3) { | 275 | if (version > 3) { |
284 | headerlen = UNSYNC(header[4], header[5], | 276 | framelen = UNSYNC(header[4], header[5], |
285 | header[6], header[7]); | 277 | header[6], header[7]); |
286 | } else { | 278 | } else { |
287 | /* version .3 files don't use synchsafe ints for | 279 | /* version .3 files don't use synchsafe ints for |
288 | * size */ | 280 | * size */ |
289 | headerlen = BYTES2INT(header[4], header[5], | 281 | framelen = BYTES2INT(header[4], header[5], |
290 | header[6], header[7]); | 282 | header[6], header[7]); |
291 | } | 283 | } |
292 | } else { | 284 | } else { |
293 | memcpy(header, (buffer + readsize), 6); | 285 | if(6 != read(fd, header, 6)) |
294 | readsize += 6; | 286 | return; |
295 | headerlen = (header[3] << 16) + | 287 | /* Adjust for the 6 bytes we read */ |
296 | (header[4] << 8) + | 288 | size -= 6; |
297 | (header[5]); | 289 | |
290 | framelen = BYTES2INT(0, header[3], header[4], header[5]); | ||
298 | } | 291 | } |
299 | 292 | ||
300 | /* Get only the part of the header that is within our buffer */ | 293 | /* Keep track of the total size */ |
301 | if(headerlen > (size-readsize)) | 294 | totframelen += framelen; |
302 | headerlen = (size - readsize); | 295 | |
296 | if(framelen == 0) | ||
297 | return; | ||
298 | |||
299 | /* If the frame is larger than the remaining buffer space we try | ||
300 | to read as much as would fit in the buffer */ | ||
301 | if(framelen >= buffersize - bufferpos) | ||
302 | framelen = buffersize - bufferpos - 1; | ||
303 | 303 | ||
304 | /* Check for certain frame headers */ | 304 | /* Check for certain frame headers */ |
305 | if(!strncmp(header, "TPE1", strlen("TPE1")) || | 305 | if(!strncmp(header, "TPE1", strlen("TPE1")) || |
306 | !strncmp(header, "TP1", strlen("TP1"))) { | 306 | !strncmp(header, "TP1", strlen("TP1"))) { |
307 | readsize++; | 307 | bytesread = read(fd, buffer + bufferpos, framelen); |
308 | headerlen--; | 308 | entry->artist = buffer + bufferpos; |
309 | artist = buffer + readsize; | 309 | unicode_munge(&entry->artist, &bytesread); |
310 | artistn = headerlen; | 310 | entry->artist[bytesread + 1] = '\0'; |
311 | unicode_munge(&artist, &artistn); | 311 | bufferpos += bytesread + 2; |
312 | size -= bytesread; | ||
312 | } | 313 | } |
313 | else if(!strncmp(header, "TIT2", strlen("TIT2")) || | 314 | else if(!strncmp(header, "TIT2", strlen("TIT2")) || |
314 | !strncmp(header, "TT2", strlen("TT2"))) { | 315 | !strncmp(header, "TT2", strlen("TT2"))) { |
315 | readsize++; | 316 | bytesread = read(fd, buffer + bufferpos, framelen); |
316 | headerlen--; | 317 | entry->title = buffer + bufferpos; |
317 | title = buffer + readsize; | 318 | unicode_munge(&entry->title, &bytesread); |
318 | titlen = headerlen; | 319 | entry->title[bytesread + 1] = '\0'; |
319 | unicode_munge(&title, &titlen); | 320 | bufferpos += bytesread + 2; |
321 | size -= bytesread; | ||
320 | } | 322 | } |
321 | else if(!strncmp(header, "TALB", strlen("TALB"))) { | 323 | else if(!strncmp(header, "TALB", strlen("TALB"))) { |
322 | readsize++; | 324 | bytesread = read(fd, buffer + bufferpos, framelen); |
323 | headerlen--; | 325 | entry->album = buffer + bufferpos; |
324 | album = buffer + readsize; | 326 | unicode_munge(&entry->album, &bytesread); |
325 | albumn = headerlen; | 327 | entry->album[bytesread + 1] = '\0'; |
326 | unicode_munge(&album, &albumn); | 328 | bufferpos += bytesread + 2; |
329 | size -= bytesread; | ||
327 | } | 330 | } |
328 | else if(!strncmp(header, "TRCK", strlen("TRCK"))) { | 331 | else if(!strncmp(header, "TRCK", strlen("TRCK"))) { |
329 | readsize++; | 332 | bytesread = read(fd, buffer + bufferpos, framelen); |
330 | headerlen--; | 333 | tracknum = buffer + bufferpos; |
331 | tracknum = buffer + readsize; | 334 | unicode_munge(&tracknum, &bytesread); |
332 | tracknumn = headerlen; | 335 | tracknum[bytesread + 1] = '\0'; |
333 | unicode_munge(&tracknum, &tracknumn); | 336 | entry->tracknum = atoi(tracknum); |
337 | bufferpos += bytesread + 1; | ||
338 | size -= bytesread; | ||
334 | } | 339 | } |
335 | |||
336 | readsize += headerlen; | ||
337 | } | ||
338 | |||
339 | if(artist) { | ||
340 | entry->artist = artist; | ||
341 | artist[artistn]=0; | ||
342 | } | ||
343 | |||
344 | if(title) { | ||
345 | entry->title = title; | ||
346 | title[titlen]=0; | ||
347 | } | ||
348 | |||
349 | if(album) { | ||
350 | entry->album = album; | ||
351 | album[albumn]=0; | ||
352 | } | ||
353 | |||
354 | if(tracknum) { | ||
355 | tracknum[tracknumn] = 0; | ||
356 | entry->tracknum = atoi(tracknum); | ||
357 | } | 340 | } |
358 | } | 341 | } |
359 | 342 | ||