It is possible to construct a rapid sequence of MPD commands that will confuse asyncio client with response order. Attached example most often makes it parse status response while expecting an idle response, which leads to a crash. Sometimes I saw the reverse, when idle output comes when a client expects status output, but it is pretty rare.
version: python-mpd2 3.0.3
Here's sample output of the script below, with some extra debugging added to the library:
pi@pi3:~/pimpd/pimpd $ /usr/bin/python3 -X dev Test2.py
Connected!
cmd: status
cmd: setvol
cmd: status
cmd: status
cmd: setvol
cmd: status
cmd: idle
_parse_list: ['volume: 16', 'repeat: 1', 'random: 0', 'single: 0', 'consume: 0', 'partition: default', 'playlist: 2', 'playlistlength: 1', 'mixrampdb: 0.000000', 'state:
play', 'song: 0', 'songid: 1', 'time: 6575:36000', 'elapsed: 6575.234', 'bitrate: 192', 'duration: 36000.104', 'audio: 44100:24:2', 'nextsong: 0', 'nextsongid: 1']
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/mpd/asyncio.py", line 279, in __run
await result._feed_from(self)
File "/usr/lib/python3/dist-packages/mpd/asyncio.py", line 45, in _feed_from
self._feed_line(line)
File "/usr/lib/python3/dist-packages/mpd/asyncio.py", line 64, in _feed_line
self.set_result(self._callback(self.__spooled_lines))
File "/usr/lib/python3/dist-packages/mpd/asyncio.py", line 273, in <lambda>
result = CommandResult("idle", subsystems, lambda result: self.__distribute_idle_result(self._parse_list(result)))
File "/usr/lib/python3/dist-packages/mpd/asyncio.py", line 313, in __distribute_idle_result
idle_changes = list(result)
File "/usr/lib/python3/dist-packages/mpd/base.py", line 265, in _parse_list
raise ProtocolError("Expected key '{}', got '{}'".format(seen, key))
mpd.base.ProtocolError: Expected key 'volume', got 'repeat'
It is possible to construct a rapid sequence of MPD commands that will confuse asyncio client with response order. Attached example most often makes it parse
status
response while expecting anidle
response, which leads to a crash. Sometimes I saw the reverse, whenidle
output comes when a client expectsstatus
output, but it is pretty rare.version:
python-mpd2 3.0.3
Here's sample output of the script below, with some extra debugging added to the library:
script to reproduce: