From a0bd5f856825d52e317e8bb3ba560cad1932ce03 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Wed, 1 Nov 2023 10:32:22 +0200 Subject: [PATCH] [Export] Improve app / file version validation. --- editor/export/editor_export_preset.cpp | 62 ++++++++++++++++++-------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/editor/export/editor_export_preset.cpp b/editor/export/editor_export_preset.cpp index 29a31c04709..b941170b7bc 100644 --- a/editor/export/editor_export_preset.cpp +++ b/editor/export/editor_export_preset.cpp @@ -334,31 +334,55 @@ Variant EditorExportPreset::get_or_env(const StringName &p_name, const String &p return get(p_name, r_valid); } +_FORCE_INLINE_ bool _check_digits(const String &p_str) { + for (int i = 0; i < p_str.length(); i++) { + char32_t c = p_str.operator[](i); + if (!is_digit(c)) { + return false; + } + } + return true; +} + String EditorExportPreset::get_version(const StringName &p_preset_string, bool p_windows_version) const { String result = get(p_preset_string); if (result.is_empty()) { result = GLOBAL_GET("application/config/version"); - if (p_windows_version) { - // Modify version number to match Windows constraints (version numbers must have 4 components). - const PackedStringArray result_split = result.split("."); - String windows_version; - if (result_split.is_empty()) { - // Use a valid fallback if the version string is empty, as a version number must be specified. - result = "1.0.0.0"; - } else if (result_split.size() == 1) { - result = result + ".0.0.0"; - } else if (result_split.size() == 2) { - result = result + ".0.0"; - } else if (result_split.size() == 3) { - result = result + ".0"; - } else { - // 4 components or more in the version string. Trim to contain only the first 4 components. - result = vformat("%s.%s.%s.%s", result_split[0] + result_split[1] + result_split[2] + result_split[3]); + // Split and validate version number components. + const PackedStringArray result_split = result.split(".", false); + bool valid_version = !result_split.is_empty(); + for (const String &E : result_split) { + if (!_check_digits(E)) { + valid_version = false; + break; + } + } + + if (valid_version) { + if (p_windows_version) { + // Modify version number to match Windows constraints (version numbers must have 4 components). + if (result_split.size() == 1) { + result = result + ".0.0.0"; + } else if (result_split.size() == 2) { + result = result + ".0.0"; + } else if (result_split.size() == 3) { + result = result + ".0"; + } else { + result = vformat("%s.%s.%s.%s", result_split[0], result_split[1], result_split[2], result_split[3]); + } + } else { + result = String(".").join(result_split); + } + } else { + if (!result.is_empty()) { + WARN_PRINT(vformat("Invalid version number \"%s\". The version number can only contain numeric characters (0-9) and non-consecutive periods (.).", result)); + } + if (p_windows_version) { + result = "1.0.0.0"; + } else { + result = "1.0.0"; } - } else if (result.is_empty()) { - // Use a valid fallback if the version string is empty, as a version number must be specified. - result = "1.0.0"; } }