aboutsummaryrefslogtreecommitdiff
path: root/libid3tag
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-03-20 14:34:46 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2011-03-20 14:34:46 +0200
commit11f9f7898f64dd344f45b3126f3fa177b9e38c4e (patch)
tree801842051654053b7fd40810331406b4733eb55e /libid3tag
parent58bc8166fca5ba0f86c07636a7ad71ee1457ec38 (diff)
downloadidest-11f9f7898f64dd344f45b3126f3fa177b9e38c4e.tar.gz
idest-11f9f7898f64dd344f45b3126f3fa177b9e38c4e.tar.bz2
libid3tag: cleanup tag.c a bit.
* libid3tag/tag.c (v2_parse): Split into several subfunctions.
Diffstat (limited to 'libid3tag')
-rw-r--r--libid3tag/tag.c505
1 files changed, 233 insertions, 272 deletions
diff --git a/libid3tag/tag.c b/libid3tag/tag.c
index 11e3b13..c23a967 100644
--- a/libid3tag/tag.c
+++ b/libid3tag/tag.c
@@ -401,324 +401,285 @@ static struct id3_tag *
401v1_parse(id3_byte_t const *data) 401v1_parse(id3_byte_t const *data)
402{ 402{
403 struct id3_tag *tag; 403 struct id3_tag *tag;
404 char title[31], artist[31], album[31], year[5], comment[31];
405 unsigned int genre, track;
404 406
405 tag = id3_tag_new(); 407 tag = id3_tag_new();
406 if (tag) { 408 if (!tag)
407 char title[31], 409 return NULL;
408 artist[31], 410
409 album[31], 411 tag->version = 0x0100;
410 year[5], 412
411 comment[31]; 413 tag->options |= ID3_TAG_OPTION_ID3V1;
412 unsigned int genre, 414 tag->options &= ~ID3_TAG_OPTION_COMPRESSION;
413 track; 415
414 416 tag->restrictions =
415 tag->version = 0x0100; 417 ID3_TAG_RESTRICTION_TEXTENCODING_LATIN1_UTF8 |
416 418 ID3_TAG_RESTRICTION_TEXTSIZE_30_CHARS;
417 tag->options |= ID3_TAG_OPTION_ID3V1; 419
418 tag->options &= ~ID3_TAG_OPTION_COMPRESSION; 420 title[30] = artist[30] = album[30] = year[4] = comment[30] = 0;
419 421
420 tag->restrictions = 422 memcpy(title, &data[3], 30);
421 ID3_TAG_RESTRICTION_TEXTENCODING_LATIN1_UTF8 | 423 memcpy(artist, &data[33], 30);
422 ID3_TAG_RESTRICTION_TEXTSIZE_30_CHARS; 424 memcpy(album, &data[63], 30);
423 425 memcpy(year, &data[93], 4);
424 title[30] = artist[30] = album[30] = year[4] = 426 memcpy(comment, &data[97], 30);
425 comment[30] = 0; 427
426 428 genre = data[127];
427 memcpy(title, &data[3], 30); 429
428 memcpy(artist, &data[33], 30); 430 track = 0;
429 memcpy(album, &data[63], 30); 431 if (comment[28] == 0 && comment[29] != 0) {
430 memcpy(year, &data[93], 4); 432 track = comment[29];
431 memcpy(comment, &data[97], 30); 433 tag->version = 0x0101;
432 434 }
433 genre = data[127];
434
435 track = 0;
436 if (comment[28] == 0 && comment[29] != 0) {
437 track = comment[29];
438 tag->version = 0x0101;
439 }
440 435
441 /* 436 /*
442 * populate tag frames 437 * populate tag frames
443 */ 438 */
444 439
445 if (v1_attachstr(tag, ID3_FRAME_TITLE, title, 0) == -1 || 440 if (v1_attachstr(tag, ID3_FRAME_TITLE, title, 0) == -1 ||
446 v1_attachstr(tag, ID3_FRAME_ARTIST, artist, 0) == -1 || 441 v1_attachstr(tag, ID3_FRAME_ARTIST, artist, 0) == -1 ||
447 v1_attachstr(tag, ID3_FRAME_ALBUM, album, 0) == -1 || 442 v1_attachstr(tag, ID3_FRAME_ALBUM, album, 0) == -1 ||
448 v1_attachstr(tag, ID3_FRAME_YEAR, year, 0) == -1 || 443 v1_attachstr(tag, ID3_FRAME_YEAR, year, 0) == -1 ||
449 (track 444 (track && v1_attachstr(tag, ID3_FRAME_TRACK, 0, track) == -1)
450 && v1_attachstr(tag, ID3_FRAME_TRACK, 0, track) == -1) 445 || (genre < 0xff
451 || (genre < 0xff 446 && v1_attachstr(tag, ID3_FRAME_GENRE, 0,
452 && v1_attachstr(tag, ID3_FRAME_GENRE, 0, 447 genre) == -1)
453 genre) == -1) 448 || v1_attachstr(tag, ID3_FRAME_COMMENT, comment,
454 || v1_attachstr(tag, ID3_FRAME_COMMENT, comment, 449 0) == -1) {
455 0) == -1) { 450 id3_tag_delete(tag);
456 id3_tag_delete(tag); 451 tag = 0;
457 tag = 0;
458 }
459 } 452 }
460 453
461 return tag; 454 return tag;
462} 455}
463 456
464static struct id3_tag * 457static int
465v2_parse(id3_byte_t const *ptr) 458v3_parse_3(struct id3_tag *tag, id3_byte_t const **pptr,
459 id3_byte_t const **pend)
466{ 460{
467 struct id3_tag *tag; 461 id3_byte_t const *ehptr, *ehend;
468 id3_byte_t *mem = 0; 462 id3_length_t ehsize;
469 463 id3_byte_t const *ptr = *pptr;
470 tag = id3_tag_new(); 464 id3_byte_t const *end = *pend;
471 if (tag) { 465
472 id3_byte_t const *end; 466 enum {
473 id3_length_t size; 467 EH_FLAG_CRC = 0x8000 /* CRC data present */
474 468 };
475 parse_header(&ptr, &tag->version, &tag->flags, &size); 469
476 470 if (end - ptr < 4)
477 tag->paddedsize = 10 + size; 471 return 1;
478 472
479 if ((tag->flags & ID3_TAG_FLAG_UNSYNCHRONISATION) && 473 ehsize = id3_parse_uint(&ptr, 4);
480 ID3_TAG_VERSION_MAJOR(tag->version) < 4) { 474
481 mem = malloc(size); 475 if (ehsize > end - ptr)
482 if (mem == 0) 476 return 1;
483 goto fail; 477
478 ehptr = ptr;
479 ehend = ptr + ehsize;
480
481 ptr = ehend;
482
483 if (ehend - ehptr >= 6) {
484 int ehflags;
485 id3_length_t padsize;
486
487 ehflags = id3_parse_uint(&ehptr, 2);
488 padsize = id3_parse_uint(&ehptr, 4);
489
490 if (padsize > end - ptr)
491 return 1;
492
493 end -= padsize;
494
495 if (ehflags & EH_FLAG_CRC) {
496 unsigned long crc;
497
498 if (ehend - ehptr < 4)
499 return 1;
500
501 crc = id3_parse_uint(&ehptr, 4);
502
503 if (crc != id3_crc_compute(ptr, end - ptr))
504 return 1;
505 tag->extendedflags |=
506 ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT;
507 }
508 }
484 509
485 memcpy(mem, ptr, size); 510 *pptr = ptr;
511 *pend = end;
512 return 0;
513}
486 514
487 size = id3_util_deunsynchronise(mem, size); 515static int
488 ptr = mem; 516verify_extended(id3_byte_t const *flagsptr,
517 id3_byte_t const *dataptr, id3_byte_t const *ehend,
518 unsigned int bytes)
519{
520 unsigned int datalen;
521 int ehflags;
522
523 while (bytes--) {
524 for (ehflags = id3_parse_uint(&flagsptr, 1); ehflags;
525 ehflags = (ehflags << 1) & 0xff) {
526 if (ehflags & 0x80) {
527 if (dataptr == ehend)
528 return 1;
529 datalen = id3_parse_uint(&dataptr, 1);
530 if (datalen > 0x7f || datalen > ehend - dataptr)
531 return 1;
532 dataptr += datalen;
533 }
489 } 534 }
535 }
536 return 0;
537}
490 538
491 end = ptr + size; 539int
540v3_parse_4(struct id3_tag *tag, id3_byte_t const **pptr, id3_byte_t const **pend)
541{
542 id3_byte_t const *ptr = *pptr;
543 id3_byte_t const *end = *pend;
544 id3_byte_t const *ehptr, *ehend;
545 id3_length_t ehsize;
546 unsigned int bytes;
547
548 if (end - ptr < 4)
549 return 1;
550
551 ehptr = ptr;
552 ehsize = id3_parse_syncsafe(&ptr, 4);
553
554 if (ehsize < 6 || ehsize > end - ehptr)
555 return 1;
556 ehend = ehptr + ehsize;
557
558 bytes = id3_parse_uint(&ptr, 1);
559
560 if (bytes < 1 || bytes > ehend - ptr)
561 return 1;
562
563 ehptr = ptr + bytes;
492 564
493 if (tag->flags & ID3_TAG_FLAG_EXTENDEDHEADER) { 565 /*
494 switch (ID3_TAG_VERSION_MAJOR(tag->version)) { 566 * verify extended header size
495 case 2: 567 */
496 goto fail; 568 if (verify_extended(ptr, ehptr, ehend, bytes))
569 return 1;
497 570
498 case 3: 571 tag->extendedflags = id3_parse_uint(&ptr, 1);
499 {
500 id3_byte_t const *ehptr,
501 *ehend;
502 id3_length_t ehsize;
503 572