From c39cae4dcfe4f087a805e9746c061fb716fb3b56 Mon Sep 17 00:00:00 2001 From: Luke Priebe Date: Tue, 28 Mar 2023 13:24:29 -0500 Subject: [PATCH] Prevent quoted arguments in editor/main_run_args from being split at spaces --- editor/editor_run.cpp | 45 ++++++++++++++++++++++++++++++++++++++++--- editor/editor_run.h | 2 ++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index cf88e424722..cf55b29a89f 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -37,6 +37,45 @@ #include "main/main.h" #include "servers/display_server.h" +/** + * Separates command line arguments without splitting up quoted strings. + */ +Vector EditorRun::_split_cmdline_args(const String &arg_string) { + Vector split_args; + int arg_start = 0; + bool is_quoted = false; + char32_t quote_char = '-'; + char32_t arg_char; + int arg_length; + for (int i = 0; i < arg_string.length(); i++) { + arg_char = arg_string[i]; + if (arg_char == '\"' || arg_char == '\'') { + if (i == 0 || arg_string[i - 1] != '\\') { + if (is_quoted) { + if (arg_char == quote_char) { + is_quoted = false; + quote_char = '-'; + } + } else { + is_quoted = true; + quote_char = arg_char; + } + } + } else if (!is_quoted && arg_char == ' ') { + arg_length = i - arg_start; + if (arg_length > 0) { + split_args.push_back(arg_string.substr(arg_start, arg_length)); + } + arg_start = i + 1; + } + } + arg_length = arg_string.length() - arg_start; + if (arg_length > 0) { + split_args.push_back(arg_string.substr(arg_start, arg_length)); + } + return split_args; +} + EditorRun::Status EditorRun::get_status() const { return status; } @@ -227,7 +266,7 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { if (placeholder_pos != -1) { // Prepend executable-specific custom arguments. // If nothing is placed before `%command%`, behave as if no placeholder was specified. - Vector exec_args = raw_custom_args.substr(0, placeholder_pos).split(" ", false); + Vector exec_args = _split_cmdline_args(raw_custom_args.substr(0, placeholder_pos)); if (exec_args.size() >= 1) { exec = exec_args[0]; exec_args.remove_at(0); @@ -243,13 +282,13 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { } // Append Godot-specific custom arguments. - custom_args = raw_custom_args.substr(placeholder_pos + String("%command%").size()).split(" ", false); + custom_args = _split_cmdline_args(raw_custom_args.substr(placeholder_pos + String("%command%").size())); for (int i = 0; i < custom_args.size(); i++) { args.push_back(custom_args[i].replace(" ", "%20")); } } else { // Append Godot-specific custom arguments. - custom_args = raw_custom_args.split(" ", false); + custom_args = _split_cmdline_args(raw_custom_args); for (int i = 0; i < custom_args.size(); i++) { args.push_back(custom_args[i].replace(" ", "%20")); } diff --git a/editor/editor_run.h b/editor/editor_run.h index 68c8742f790..686a436b03f 100644 --- a/editor/editor_run.h +++ b/editor/editor_run.h @@ -47,6 +47,8 @@ private: Status status; String running_scene; + Vector _split_cmdline_args(const String &arg_string); + public: Status get_status() const; String get_running_scene() const;