Skip to content

Commit

Permalink
Fix #1666: malformed binary data in SoundCheck
Browse files Browse the repository at this point in the history
  • Loading branch information
sampsyo committed Nov 13, 2015
1 parent 2048aa6 commit 9c96845
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 6 deletions.
4 changes: 2 additions & 2 deletions beets/mediafile.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,9 @@ def _sc_decode(soundcheck):
# SoundCheck tags consist of 10 numbers, each represented by 8
# characters of ASCII hex preceded by a space.
try:
soundcheck = soundcheck.replace(' ', '').decode('hex')
soundcheck = soundcheck.replace(b' ', b'').decode('hex')
soundcheck = struct.unpack(b'!iiiiiiiiii', soundcheck)
except (struct.error, TypeError, UnicodeEncodeError):
except (struct.error, TypeError):
# SoundCheck isn't in the format we expect, so return default
# values.
return 0.0, 0.0
Expand Down
2 changes: 2 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ Fixes:
* :doc:`/plugins/duplicates`: Fix a crash when merging items. :bug:`1699`
* :doc:`/plugins/smartplaylist`: More gracefully handle malformed queries and
missing configuration.
* Fix a crash with some files with unreadable iTunes SoundCheck metadata.
:bug:`1666`

.. _Emby Server: http://emby.media

Expand Down
Binary file added test/rsrc/soundcheck-nonascii.m4a
Binary file not shown.
15 changes: 11 additions & 4 deletions test/test_mediafile_edge.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ def test_only_magic_bytes_jpeg(self):
beets.mediafile._image_mime_type(jpg_data),
'image/jpeg')

def test_soundcheck_non_ascii(self):
# Make sure we don't crash when the iTunes SoundCheck field contains
# non-ASCII binary data.
f = beets.mediafile.MediaFile(os.path.join(_common.RSRC,
'soundcheck-nonascii.m4a'))
self.assertEqual(f.rg_track_gain, 0.0)


class InvalidValueToleranceTest(unittest.TestCase):

Expand Down Expand Up @@ -269,19 +276,19 @@ def test_round_trip(self):
self.assertEqual(peak, 1.0)

def test_decode_zero(self):
data = u' 80000000 80000000 00000000 00000000 00000000 00000000 ' \
u'00000000 00000000 00000000 00000000'
data = b' 80000000 80000000 00000000 00000000 00000000 00000000 ' \
b'00000000 00000000 00000000 00000000'
gain, peak = beets.mediafile._sc_decode(data)
self.assertEqual(gain, 0.0)
self.assertEqual(peak, 0.0)

def test_malformatted(self):
gain, peak = beets.mediafile._sc_decode(u'foo')
gain, peak = beets.mediafile._sc_decode(b'foo')
self.assertEqual(gain, 0.0)
self.assertEqual(peak, 0.0)

def test_special_characters(self):
gain, peak = beets.mediafile._sc_decode(u'caf\xe9')
gain, peak = beets.mediafile._sc_decode(u'caf\xe9'.encode('utf8'))
self.assertEqual(gain, 0.0)
self.assertEqual(peak, 0.0)

Expand Down

0 comments on commit 9c96845

Please sign in to comment.