diff --git a/docs/changelog.rst b/docs/changelog.rst index df235d1d..e77cd948 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -106,6 +106,9 @@ of the following extensions as well: e.g. HTTP radio streams and not just ``local:track:...`` URIs. This used to work, but was broken in Mopidy 0.15.0. (Fixes: :issue:`527`) +- Fixed crash when playing ``local:track:...`` URIs which contained non-ASCII + chars after uridecode. + **MPD frontend** - Made the formerly unused commands ``outputs``, ``enableoutput``, and diff --git a/mopidy/backends/local/playback.py b/mopidy/backends/local/playback.py index eda06ff7..98c92a85 100644 --- a/mopidy/backends/local/playback.py +++ b/mopidy/backends/local/playback.py @@ -13,7 +13,7 @@ class LocalPlaybackProvider(base.BasePlaybackProvider): def change_track(self, track): media_dir = self.backend.config['local']['media_dir'] # TODO: check that type is correct. - file_path = path.uri_to_path(track.uri).split(':', 1)[1] + file_path = path.uri_to_path(track.uri).split(b':', 1)[1] file_path = os.path.join(media_dir, file_path) track = track.copy(uri=path.path_to_uri(file_path)) return super(LocalPlaybackProvider, self).change_track(track) diff --git a/tests/backends/local/playback_test.py b/tests/backends/local/playback_test.py index ab135766..8fbc4415 100644 --- a/tests/backends/local/playback_test.py +++ b/tests/backends/local/playback_test.py @@ -72,6 +72,14 @@ class LocalPlaybackProviderTest(unittest.TestCase): self.playback.play() self.assertEqual(self.playback.state, PlaybackState.PLAYING) + def test_play_uri_with_non_ascii_bytes(self): + # Regression test: If trying to do .split(u':') on a bytestring, the + # string will be decoded from ASCII to Unicode, which will crash on + # non-ASCII strings, like the bytestring the following URI decodes to. + self.add_track('local:track:12%20Doin%E2%80%99%20It%20Right.flac') + self.playback.play() + self.assertEqual(self.playback.state, PlaybackState.PLAYING) + def test_initial_state_is_stopped(self): self.assertEqual(self.playback.state, PlaybackState.STOPPED)