Fix #7969: limit recursion during alias execution

This commit is contained in:
glx 2020-02-01 22:08:05 +01:00 committed by glx22
parent ac7cc18ab9
commit b5d56559d2
2 changed files with 12 additions and 6 deletions

View File

@ -21,6 +21,7 @@
#include "safeguards.h" #include "safeguards.h"
static const uint ICON_TOKEN_COUNT = 20; ///< Maximum number of tokens in one command static const uint ICON_TOKEN_COUNT = 20; ///< Maximum number of tokens in one command
static const uint ICON_MAX_RECURSE = 10; ///< Maximum number of recursion
/* console parser */ /* console parser */
IConsoleCmd *_iconsole_cmds; ///< list of registered commands IConsoleCmd *_iconsole_cmds; ///< list of registered commands
@ -316,13 +317,18 @@ IConsoleAlias *IConsoleAliasGet(const char *name)
* @param tokencount the number of parameters passed * @param tokencount the number of parameters passed
* @param *tokens are the parameters given to the original command (0 is the first param) * @param *tokens are the parameters given to the original command (0 is the first param)
*/ */
static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char *tokens[ICON_TOKEN_COUNT]) static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char *tokens[ICON_TOKEN_COUNT], const uint recurse_count)
{ {
char alias_buffer[ICON_MAX_STREAMSIZE] = { '\0' }; char alias_buffer[ICON_MAX_STREAMSIZE] = { '\0' };
char *alias_stream = alias_buffer; char *alias_stream = alias_buffer;
DEBUG(console, 6, "Requested command is an alias; parsing..."); DEBUG(console, 6, "Requested command is an alias; parsing...");
if (recurse_count > ICON_MAX_RECURSE) {
IConsoleError("Too many alias expansions, recursion limit reached. Aborting");
return;
}
for (const char *cmdptr = alias->cmdline; *cmdptr != '\0'; cmdptr++) { for (const char *cmdptr = alias->cmdline; *cmdptr != '\0'; cmdptr++) {
switch (*cmdptr) { switch (*cmdptr) {
case '\'': // ' will double for "" case '\'': // ' will double for ""
@ -330,7 +336,7 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char
break; break;
case ';': // Cmd separator; execute previous and start new command case ';': // Cmd separator; execute previous and start new command
IConsoleCmdExec(alias_buffer); IConsoleCmdExec(alias_buffer, recurse_count);
alias_stream = alias_buffer; alias_stream = alias_buffer;
*alias_stream = '\0'; // Make sure the new command is terminated. *alias_stream = '\0'; // Make sure the new command is terminated.
@ -390,7 +396,7 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char
} }
} }
IConsoleCmdExec(alias_buffer); IConsoleCmdExec(alias_buffer, recurse_count);
} }
/** /**
@ -398,7 +404,7 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char
* individual tokens (separated by spaces), then execute it if possible * individual tokens (separated by spaces), then execute it if possible
* @param cmdstr string to be parsed and executed * @param cmdstr string to be parsed and executed
*/ */
void IConsoleCmdExec(const char *cmdstr) void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
{ {
const char *cmdptr; const char *cmdptr;
char *tokens[ICON_TOKEN_COUNT], tokenstream[ICON_MAX_STREAMSIZE]; char *tokens[ICON_TOKEN_COUNT], tokenstream[ICON_MAX_STREAMSIZE];
@ -504,7 +510,7 @@ void IConsoleCmdExec(const char *cmdstr)
t_index--; t_index--;
IConsoleAlias *alias = IConsoleAliasGet(tokens[0]); IConsoleAlias *alias = IConsoleAliasGet(tokens[0]);
if (alias != nullptr) { if (alias != nullptr) {
IConsoleAliasExec(alias, t_index, &tokens[1]); IConsoleAliasExec(alias, t_index, &tokens[1], recurse_count + 1);
return; return;
} }

View File

@ -28,7 +28,7 @@ void IConsoleWarning(const char *string);
void IConsoleError(const char *string); void IConsoleError(const char *string);
/* Parser */ /* Parser */
void IConsoleCmdExec(const char *cmdstr); void IConsoleCmdExec(const char *cmdstr, const uint recurse_count = 0);
bool IsValidConsoleColour(TextColour c); bool IsValidConsoleColour(TextColour c);