diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-06-21 10:18:37 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-06-21 10:18:37 +0200 |
commit | 78518be1946da573232731489e19cc74ea5f4d10 (patch) | |
tree | 0ae7b90da5952f6a425ed9f57e59c1874474a7da | |
parent | 9e56f28d0e77530f21bd38d1ef5dfb9b31072818 (diff) | |
parent | c39cae4dcfe4f087a805e9746c061fb716fb3b56 (diff) | |
download | redot-engine-78518be1946da573232731489e19cc74ea5f4d10.tar.gz |
Merge pull request #75444 from lpriebe/editor-run-arg-split-fix
Prevent quoted args in `editor/main_run_args` from being split at spaces
-rw-r--r-- | editor/editor_run.cpp | 45 | ||||
-rw-r--r-- | 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 25c25c3f7c..42cd858581 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<String> EditorRun::_split_cmdline_args(const String &arg_string) { + Vector<String> 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; } @@ -232,7 +271,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<String> exec_args = raw_custom_args.substr(0, placeholder_pos).split(" ", false); + Vector<String> 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); @@ -248,13 +287,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 bd6770ae3d..01904489cc 100644 --- a/editor/editor_run.h +++ b/editor/editor_run.h @@ -47,6 +47,8 @@ private: Status status; String running_scene; + Vector<String> _split_cmdline_args(const String &arg_string); + public: Status get_status() const; String get_running_scene() const; |