1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00

Fix infinite loop in protocolServerProcess() on error.

The error was written to the client and then another command read. If the write did not fail then the loop would never exit.

Instead exit on any error that is not raised by the command handler as we can pretty safely assume this is an unrecoverable protocol error. The command handler might throw a protocol error itself, but this should be caught in the next read or write in the main loop.
This commit is contained in:
David Steele 2021-08-18 09:48:37 -04:00
parent 9a6afe3fc1
commit d69a596358
2 changed files with 15 additions and 4 deletions

View File

@ -224,8 +224,9 @@ protocolServerProcess(
// sure the remote does not timeout.
protocolKeepAlive();
}
// Else report error to the client
else
RETHROW();
protocolServerError(this, errorCode(), STR(errorMessage()), STR(errorStackTrace()));
}
TRY_END();
}
@ -263,6 +264,9 @@ protocolServerProcess(
{
// Report error to the client
protocolServerError(this, errorCode(), STR(errorMessage()), STR(errorStackTrace()));
// Rethrow so the process exits with an error
RETHROW();
}
TRY_END();
}

View File

@ -482,7 +482,7 @@ testRun(void)
ioWriteFlush(HRN_FORK_CHILD_WRITE());
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("server");
TEST_TITLE("server with error");
ProtocolServer *server = NULL;
@ -500,7 +500,14 @@ testRun(void)
const ProtocolServerHandler commandHandler[] = {TEST_PROTOCOL_SERVER_HANDLER_LIST};
// This cannot run in a TEST* macro because tests are run by the command handlers
TEST_ERROR(
protocolServerProcess(server, NULL, commandHandler, PROTOCOL_SERVER_HANDLER_LIST_SIZE(commandHandler)),
ProtocolError, "invalid command 'BOGUS' (0x38eacd271)");
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("server restart");
// This does not run in a TEST* macro because tests are run by the command handlers
protocolServerProcess(server, NULL, commandHandler, PROTOCOL_SERVER_HANDLER_LIST_SIZE(commandHandler));
// -----------------------------------------------------------------------------------------------------------------
@ -513,7 +520,7 @@ testRun(void)
server, protocolServerNew(STRDEF("test server"), STRDEF("test"), HRN_FORK_CHILD_READ(), HRN_FORK_CHILD_WRITE()),
"new server");
// This cannot run in a TEST* macro because tests are run by the command handlers
// This does not run in a TEST* macro because tests are run by the command handlers
protocolServerProcess(server, retryList, commandHandler, PROTOCOL_SERVER_HANDLER_LIST_SIZE(commandHandler));
}
HRN_FORK_CHILD_END();