diff options
Diffstat (limited to 'firmware/id3.c')
-rw-r--r-- | firmware/id3.c | 88 |
1 files changed, 57 insertions, 31 deletions
diff --git a/firmware/id3.c b/firmware/id3.c index 2f933b6b6d..f797ed891b 100644 --- a/firmware/id3.c +++ b/firmware/id3.c | |||
@@ -186,6 +186,24 @@ static bool setid3v1title(int fd, struct mp3entry *entry) | |||
186 | return true; | 186 | return true; |
187 | } | 187 | } |
188 | 188 | ||
189 | static int read_frame(int fd, unsigned char *buf, char **destptr, int framelen) | ||
190 | { | ||
191 | int bytesread; | ||
192 | |||
193 | bytesread = read(fd, buf, framelen); | ||
194 | if(bytesread < 0) | ||
195 | return bytesread * 10 - 1; | ||
196 | |||
197 | if(bytesread < framelen) | ||
198 | return -1; | ||
199 | |||
200 | *destptr = buf; | ||
201 | if(unicode_munge(destptr, &bytesread) < 0) | ||
202 | return -2; | ||
203 | |||
204 | (*destptr)[bytesread] = '\0'; | ||
205 | return bytesread + 1; | ||
206 | } | ||
189 | 207 | ||
190 | /* | 208 | /* |
191 | * Sets the title of an MP3 entry based on its ID3v2 tag. | 209 | * Sets the title of an MP3 entry based on its ID3v2 tag. |
@@ -203,7 +221,7 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
203 | char header[10]; | 221 | char header[10]; |
204 | unsigned char version; | 222 | unsigned char version; |
205 | char *buffer = entry->id3v2buf; | 223 | char *buffer = entry->id3v2buf; |
206 | char *tracknum = NULL; | 224 | char *tmp = NULL; |
207 | int bytesread = 0; | 225 | int bytesread = 0; |
208 | int buffersize = sizeof(entry->id3v2buf); | 226 | int buffersize = sizeof(entry->id3v2buf); |
209 | int flags; | 227 | int flags; |
@@ -339,56 +357,64 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
339 | if (!entry->artist && | 357 | if (!entry->artist && |
340 | (!strncmp(header, "TPE1", strlen("TPE1")) || | 358 | (!strncmp(header, "TPE1", strlen("TPE1")) || |
341 | !strncmp(header, "TP1", strlen("TP1")))) { | 359 | !strncmp(header, "TP1", strlen("TP1")))) { |
342 | bytesread = read(fd, buffer + bufferpos, framelen); | 360 | bytesread = read_frame(fd, buffer + bufferpos, |
343 | entry->artist = buffer + bufferpos; | 361 | &entry->artist, framelen); |
344 | unicode_munge(&entry->artist, &bytesread); | 362 | if(bytesread < 0) |
345 | entry->artist[bytesread + 1] = '\0'; | 363 | return; |
346 | bufferpos += bytesread + 2; | 364 | |
347 | size -= bytesread; | 365 | bufferpos += bytesread; |
366 | size -= framelen; | ||
348 | } | 367 | } |
349 | else if (!entry->title && | 368 | else if (!entry->title && |
350 | (!strncmp(header, "TIT2", strlen("TIT2")) || | 369 | (!strncmp(header, "TIT2", strlen("TIT2")) || |
351 | !strncmp(header, "TT2", strlen("TT2")))) { | 370 | !strncmp(header, "TT2", strlen("TT2")))) { |
352 | bytesread = read(fd, buffer + bufferpos, framelen); | 371 | bytesread = read_frame(fd, buffer + bufferpos, |
353 | entry->title = buffer + bufferpos; | 372 | &entry->title, framelen); |
354 | unicode_munge(&entry->title, &bytesread); | 373 | if(bytesread < 0) |
355 | entry->title[bytesread + 1] = '\0'; | 374 | return; |
356 | bufferpos += bytesread + 2; | 375 | |
357 | size -= bytesread; | 376 | bufferpos += bytesread; |
377 | size -= framelen; | ||
358 | } | 378 | } |
359 | else if( !entry->album && | 379 | else if( !entry->album && |
360 | !strncmp(header, "TALB", strlen("TALB"))) { | 380 | !strncmp(header, "TALB", strlen("TALB"))) { |
361 | bytesread = read(fd, buffer + bufferpos, framelen); | 381 | bytesread = read_frame(fd, buffer + bufferpos, |
362 | entry->album = buffer + bufferpos; | 382 | &entry->album, framelen); |
363 | unicode_munge(&entry->album, &bytesread); | 383 | if(bytesread < 0) |
364 | entry->album[bytesread + 1] = '\0'; | 384 | return; |
365 | bufferpos += bytesread + 2; | 385 | |
366 | size -= bytesread; | 386 | bufferpos += bytesread; |
387 | size -= framelen; | ||
367 | } | 388 | } |
368 | else if (!entry->tracknum && | 389 | else if (!entry->tracknum && |
369 | !strncmp(header, "TRCK", strlen("TRCK"))) { | 390 | !strncmp(header, "TRCK", strlen("TRCK"))) { |
370 | bytesread = read(fd, buffer + bufferpos, framelen); | 391 | bytesread = read_frame(fd, buffer + bufferpos, |
371 | tracknum = buffer + bufferpos; | 392 | &tmp, framelen); |
372 | unicode_munge(&tracknum, &bytesread); | 393 | if(bytesread < 0) |
373 | tracknum[bytesread + 1] = '\0'; | 394 | return; |
374 | entry->tracknum = atoi(tracknum); | 395 | |
375 | bufferpos += bytesread + 1; | 396 | entry->tracknum = atoi(tmp); |
376 | size -= bytesread; | 397 | |
398 | size -= framelen; | ||
377 | } | 399 | } |
378 | else if (!entry->year && | 400 | else if (!entry->year && |
379 | (!strncmp(header, "TYER", 4) || | 401 | (!strncmp(header, "TYER", 4) || |
380 | !strncmp(header, "TYR", 3))) { | 402 | !strncmp(header, "TYR", 3))) { |
381 | char* ptr = buffer + bufferpos; | 403 | bytesread = read_frame(fd, buffer + bufferpos, |
382 | bytesread = read(fd, ptr, framelen); | 404 | &tmp, framelen); |
383 | unicode_munge(&ptr, &bytesread); | 405 | if(bytesread < 0) |
384 | entry->year = atoi(ptr); | 406 | return; |
385 | bufferpos += bytesread + 1; | 407 | |
408 | entry->year = atoi(tmp); | ||
386 | size -= bytesread; | 409 | size -= bytesread; |
387 | } | 410 | } |
388 | else if (!entry->genre && | 411 | else if (!entry->genre && |
389 | !strncmp(header, "TCON", 4)) { | 412 | !strncmp(header, "TCON", 4)) { |
390 | char* ptr = buffer + bufferpos; | 413 | char* ptr = buffer + bufferpos; |
391 | bytesread = read(fd, ptr, framelen); | 414 | bytesread = read(fd, ptr, framelen); |
415 | if(bytesread < 0 || bytesread < framelen) | ||
416 | return; | ||
417 | |||
392 | if (ptr[1] == '(' && ptr[2] != '(') | 418 | if (ptr[1] == '(' && ptr[2] != '(') |
393 | entry->genre = atoi(ptr+2); | 419 | entry->genre = atoi(ptr+2); |
394 | bufferpos += bytesread + 1; | 420 | bufferpos += bytesread + 1; |