diff --git a/NEWS.txt b/NEWS.txt index b98f5c5b2..f5a7c4fd0 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -36,6 +36,7 @@ * Add %_musicbrainz_tracknumber% to hold track # as shown on MusicBrainz release web-page e.g. vinyl/cassette style A1, A2, B1, B2 * Show the ID3 version of the file in the Info... dialog (Ctrl-I) (PICARD-218) + * Fixed a bug where Picard crashed if a MP3 file had malformed TRCK or TPOS tags (PICARD-112) Version 1.2 - 2013-03-30 diff --git a/picard/formats/id3.py b/picard/formats/id3.py index 5b480e927..f9b8f3d3d 100644 --- a/picard/formats/id3.py +++ b/picard/formats/id3.py @@ -20,6 +20,7 @@ import mutagen.apev2 import mutagen.mp3 import mutagen.trueaudio +import re from collections import defaultdict from mutagen import id3 from picard import config, log @@ -175,6 +176,10 @@ class ID3File(File): __other_supported_tags = ("discnumber", "tracknumber", "totaldiscs", "totaltracks") + __tag_re_parse = { + 'TRCK': re.compile(r'^(?P\d+)(?:/(?P\d+))?$'), + 'TPOS': re.compile(r'^(?P\d+)(?:/(?P\d+))?$') + } def __init__(self, filename): super(ID3File, self).__init__(filename) @@ -239,18 +244,14 @@ class ID3File(File): metadata.add(name, unicode(frame.text)) elif frameid == 'UFID' and frame.owner == 'http://musicbrainz.org': metadata['musicbrainz_recordingid'] = frame.data.decode('ascii', 'ignore') - elif frameid == 'TRCK': - value = frame.text[0].split('/') - if len(value) > 1: - metadata['tracknumber'], metadata['totaltracks'] = value[:2] + elif frameid in self.__tag_re_parse.keys(): + m = self.__tag_re_parse[frameid].search(frame.text[0]) + if m: + for name, value in m.groupdict().iteritems(): + if value is not None: + metadata[name] = value else: - metadata['tracknumber'] = value[0] - elif frameid == 'TPOS': - value = frame.text[0].split('/') - if len(value) > 1: - metadata['discnumber'], metadata['totaldiscs'] = value[:2] - else: - metadata['discnumber'] = value[0] + log.error("Invalid %s value '%s' dropped in %r", frameid, frame.text[0], filename) elif frameid == 'APIC': extras = { 'desc': frame.desc,