diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-03-20 14:34:46 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-03-20 14:34:46 +0200 |
commit | 11f9f7898f64dd344f45b3126f3fa177b9e38c4e (patch) | |
tree | 801842051654053b7fd40810331406b4733eb55e /libid3tag | |
parent | 58bc8166fca5ba0f86c07636a7ad71ee1457ec38 (diff) | |
download | idest-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.c | 505 |
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 * | |||
401 | v1_parse(id3_byte_t const *data) | 401 | v1_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 | ||
464 | static struct id3_tag * | 457 | static int |
465 | v2_parse(id3_byte_t const *ptr) | 458 | v3_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); | 515 | static int |
488 | ptr = mem; | 516 | verify_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; | 539 | int |
540 | v3_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 | ||