From 6c9f9c136b72b4453c39eca4edb70b48f53b8d2c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 20 Aug 2019 20:31:36 +0200 Subject: [PATCH] command/all: don't create new Response instance in exception handler The new Response instance in the `catch` block didn't have the `command` attribute set, so the error response didn't indicate which command had failed, which however is required in the MPD protocol. Closes https://github.com/MusicPlayerDaemon/MPD/issues/628 --- NEWS | 2 ++ src/command/AllCommands.cxx | 47 +++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/NEWS b/NEWS index d47a02aff..e1859419f 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ ver 0.21.14 (not yet released) * player - fix crash after song change - fix seek position after restarting the decoder +* protocol + - include command name in error responses ver 0.21.13 (2019/08/06) * input diff --git a/src/command/AllCommands.cxx b/src/command/AllCommands.cxx index a9fac6919..7926b7128 100644 --- a/src/command/AllCommands.cxx +++ b/src/command/AllCommands.cxx @@ -363,7 +363,7 @@ command_checked_lookup(Response &r, unsigned permission, CommandResult command_process(Client &client, unsigned num, char *line) noexcept -try { +{ Response r(client, num); /* get the command name (first word on the line) */ @@ -391,32 +391,33 @@ try { char *argv[COMMAND_ARGV_MAX]; Request args(argv, 0); - /* now parse the arguments (quoted or unquoted) */ + try { + /* now parse the arguments (quoted or unquoted) */ - while (true) { - if (args.size == COMMAND_ARGV_MAX) { - r.Error(ACK_ERROR_ARG, "Too many arguments"); - return CommandResult::ERROR; + while (true) { + if (args.size == COMMAND_ARGV_MAX) { + r.Error(ACK_ERROR_ARG, "Too many arguments"); + return CommandResult::ERROR; + } + + char *a = tokenizer.NextParam(); + if (a == nullptr) + break; + + argv[args.size++] = a; } - char *a = tokenizer.NextParam(); - if (a == nullptr) - break; + /* look up and invoke the command handler */ - argv[args.size++] = a; - } + const struct command *cmd = + command_checked_lookup(r, client.GetPermission(), + cmd_name, args); + if (cmd == nullptr) + return CommandResult::ERROR; - /* look up and invoke the command handler */ - - const struct command *cmd = - command_checked_lookup(r, client.GetPermission(), - cmd_name, args); - if (cmd == nullptr) + return cmd->handler(client, args, r); + } catch (...) { + PrintError(r, std::current_exception()); return CommandResult::ERROR; - - return cmd->handler(client, args, r); -} catch (...) { - Response r(client, num); - PrintError(r, std::current_exception()); - return CommandResult::ERROR; + } }