Skip to content

Commit

Permalink
replaygain: Handle invalid XML output from bs1770gain
Browse files Browse the repository at this point in the history
  • Loading branch information
jackwilsdon committed May 1, 2019
1 parent 6ec061b commit a075008
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 11 deletions.
9 changes: 8 additions & 1 deletion beetsplug/replaygain.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,14 @@ def end_element_handler(name):
state['gain'] = state['peak'] = None
parser.StartElementHandler = start_element_handler
parser.EndElementHandler = end_element_handler
parser.Parse(text, True)

try:
parser.Parse(text, True)
except xml.parsers.expat.ExpatError:
raise ReplayGainError(u'bs1770gain returned malformed XML - this '
'is a bug in versions prior to v0.4.10, '
'please ensure that your version is up to '
'date')

if len(per_file_gain) != len(path_list):
raise ReplayGainError(
Expand Down
62 changes: 52 additions & 10 deletions test/test_replaygain.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import unittest
import six

from test.helper import TestHelper, has_program
from mock import patch
from test.helper import TestHelper, capture_log, has_program

from beets import config
from beets.mediafile import MediaFile
Expand All @@ -44,6 +45,15 @@
LOUDNESS_PROG_AVAILABLE = False


def reset_replaygain(item):
item['rg_track_peak'] = None
item['rg_track_gain'] = None
item['rg_album_gain'] = None
item['rg_album_gain'] = None
item.write()
item.store()


class ReplayGainCliTestBase(TestHelper):

def setUp(self):
Expand All @@ -68,20 +78,12 @@ def setUp(self):

album = self.add_album_fixture(2)
for item in album.items():
self._reset_replaygain(item)
reset_replaygain(item)

def tearDown(self):
self.teardown_beets()
self.unload_plugins()

def _reset_replaygain(self, item):
item['rg_track_peak'] = None
item['rg_track_gain'] = None
item['rg_album_gain'] = None
item['rg_album_gain'] = None
item.write()
item.store()

def test_cli_saves_track_gain(self):
for item in self.lib.items():
self.assertIsNone(item.rg_track_peak)
Expand Down Expand Up @@ -166,6 +168,46 @@ class ReplayGainLdnsCliTest(ReplayGainCliTestBase, unittest.TestCase):
backend = u'bs1770gain'


class ReplayGainLdnsCliMalformedTest(TestHelper, unittest.TestCase):

@patch('beetsplug.replaygain.call')
def setUp(self, call_patch):
self.setup_beets()
self.config['replaygain']['backend'] = 'bs1770gain'

# Patch call to return nothing, bypassing the bs1770gain installation
# check.
call_patch.return_value = None
self.load_plugins('replaygain')

for item in self.add_album_fixture(2).items():
reset_replaygain(item)

@patch('beetsplug.replaygain.call')
def test_malformed_output(self, call_patch):
# Return malformed XML (the ampersand should be &)
call_patch.return_value = """
<album>
<track total="1" number="1" file="&">
<integrated lufs="0" lu="0" />
<sample-peak spfs="0" factor="0" />
</track>
</album>
"""

with capture_log('beets.replaygain') as logs:
self.run_command('replaygain')

# Count how many lines match the expected error.
matching = [line for line in logs if
line == 'replaygain: ReplayGain error: bs1770gain '
'returned malformed XML - this is a bug in '
'versions prior to v0.4.10, please ensure that '
'your version is up to date']

self.assertEqual(len(matching), 2)


def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

Expand Down

0 comments on commit a075008

Please sign in to comment.