diff options
author | glx <glx@openttd.org> | 2020-02-01 22:08:05 +0100 |
---|---|---|
committer | glx22 <glx22@users.noreply.github.com> | 2020-02-04 18:41:38 +0100 |
commit | b5d56559d2ec16512dd8a0346406bf36486ebf7c (patch) | |
tree | ad89844fbe079adb149c307634c0d83f2d4d2217 | |
parent | ac7cc18ab9f5a06ac0261a69dc96a28e3f1136af (diff) | |
download | openttd-b5d56559d2ec16512dd8a0346406bf36486ebf7c.tar.xz |
Fix #7969: limit recursion during alias execution
-rw-r--r-- | src/console.cpp | 16 | ||||
-rw-r--r-- | src/console_func.h | 2 |
2 files changed, 12 insertions, 6 deletions
diff --git a/src/console.cpp b/src/console.cpp index b777bf2c0..3c782357d 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -21,6 +21,7 @@ #include "safeguards.h" 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 */ IConsoleCmd *_iconsole_cmds; ///< list of registered commands @@ -316,13 +317,18 @@ IConsoleAlias *IConsoleAliasGet(const char *name) * @param tokencount the number of parameters passed * @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_stream = alias_buffer; 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++) { switch (*cmdptr) { case '\'': // ' will double for "" @@ -330,7 +336,7 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char break; case ';': // Cmd separator; execute previous and start new command - IConsoleCmdExec(alias_buffer); + IConsoleCmdExec(alias_buffer, recurse_count); alias_stream = alias_buffer; *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 * @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; char *tokens[ICON_TOKEN_COUNT], tokenstream[ICON_MAX_STREAMSIZE]; @@ -504,7 +510,7 @@ void IConsoleCmdExec(const char *cmdstr) t_index--; IConsoleAlias *alias = IConsoleAliasGet(tokens[0]); if (alias != nullptr) { - IConsoleAliasExec(alias, t_index, &tokens[1]); + IConsoleAliasExec(alias, t_index, &tokens[1], recurse_count + 1); return; } diff --git a/src/console_func.h b/src/console_func.h index 1dad477b8..6d634a455 100644 --- a/src/console_func.h +++ b/src/console_func.h @@ -28,7 +28,7 @@ void IConsoleWarning(const char *string); void IConsoleError(const char *string); /* Parser */ -void IConsoleCmdExec(const char *cmdstr); +void IConsoleCmdExec(const char *cmdstr, const uint recurse_count = 0); bool IsValidConsoleColour(TextColour c); |