From 6ebf3a93d19cf78117a61edf52cb6db9f1b848b4 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:56:29 -0500 Subject: [PATCH] Added protection in the register python script queries of the default folders against a non-existent key causing a KeyError in python (#1946) Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- .../ProjectManager/Source/PythonBindings.cpp | 17 +++++++---- scripts/o3de/o3de/register.py | 29 ++++++++++--------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index 167cf6d10e..f8e90b0a59 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -394,13 +394,20 @@ namespace O3DE::ProjectManager if (pybind11::isinstance(o3deData)) { engineInfo.m_path = Py_To_String(enginePath); - engineInfo.m_defaultGemsFolder = Py_To_String(o3deData["default_gems_folder"]); - engineInfo.m_defaultProjectsFolder = Py_To_String(o3deData["default_projects_folder"]); - engineInfo.m_defaultRestrictedFolder = Py_To_String(o3deData["default_restricted_folder"]); - engineInfo.m_defaultTemplatesFolder = Py_To_String(o3deData["default_templates_folder"]); + auto defaultGemsFolder = m_manifest.attr("get_o3de_gems_folder")(); + engineInfo.m_defaultGemsFolder = Py_To_String_Optional(o3deData, "default_gems_folder", Py_To_String(defaultGemsFolder)); + + auto defaultProjectsFolder = m_manifest.attr("get_o3de_projects_folder")(); + engineInfo.m_defaultProjectsFolder = Py_To_String_Optional(o3deData, "default_projects_folder", Py_To_String(defaultProjectsFolder)); + + auto defaultRestrictedFolder = m_manifest.attr("get_o3de_restricted_folder")(); + engineInfo.m_defaultRestrictedFolder = Py_To_String_Optional(o3deData, "default_restricted_folder", Py_To_String(defaultRestrictedFolder)); + + auto defaultTemplatesFolder = m_manifest.attr("get_o3de_templates_folder")(); + engineInfo.m_defaultTemplatesFolder = Py_To_String_Optional(o3deData, "default_templates_folder", Py_To_String(defaultTemplatesFolder)); auto defaultThirdPartyFolder = m_manifest.attr("get_o3de_third_party_folder")(); - engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData,"default_third_party_folder", Py_To_String(defaultThirdPartyFolder)); + engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData, "default_third_party_folder", Py_To_String(defaultThirdPartyFolder)); } auto engineData = m_manifest.attr("get_engine_json_data")(pybind11::none(), enginePath); diff --git a/scripts/o3de/o3de/register.py b/scripts/o3de/o3de/register.py index ff4ccdc0a6..9d1d6e3122 100644 --- a/scripts/o3de/o3de/register.py +++ b/scripts/o3de/o3de/register.py @@ -253,7 +253,8 @@ def add_engine_name_to_path(json_data: dict, engine_path: pathlib.Path, force: b logger.error( f'Attempting to register existing engine "{engine_name}" with a new path of {engine_path.as_posix()}.' f' The current path is {pathlib.Path(engines_path_json[engine_name]).as_posix()}.' - f' To force registration of a new engine path, specify the -f/--force option.') + f' To force registration of a new engine path, specify the -f/--force option.' + f'\nAlternatively the engine can be registered with a different name by changing the "engine_name" field in the engine.json.') return 1 engines_path_json[engine_name] = engine_path.as_posix() return 0 @@ -665,7 +666,7 @@ def remove_invalid_o3de_projects(manifest_path: pathlib.Path = None) -> int: result = 0 - for project in json_data['projects']: + for project in json_data.get('projects', []): if not validation.valid_o3de_project_json(pathlib.Path(project).resolve() / 'project.json'): logger.warn(f"Project path {project} is invalid.") # Attempt to unregister all invalid projects even if previous projects failed to unregister @@ -677,36 +678,36 @@ def remove_invalid_o3de_projects(manifest_path: pathlib.Path = None) -> int: def remove_invalid_o3de_objects() -> None: json_data = manifest.load_o3de_manifest() - for engine_object in json_data['engines']: - engine_path = engine_object['path'] + for engine_object in json_data.get('engines', []): + engine_path = engine_object.get('path', '') if not validation.valid_o3de_engine_json(pathlib.Path(engine_path).resolve() / 'engine.json'): logger.warn(f"Engine path {engine_path} is invalid.") register(engine_path=engine_path, remove=True) remove_invalid_o3de_projects() - for gem in json_data['gems']: + for gem in json_data.get('gems', []): if not validation.valid_o3de_gem_json(pathlib.Path(gem).resolve() / 'gem.json'): logger.warn(f"Gem path {gem} is invalid.") register(gem_path=gem, remove=True) - for external in json_data['external_subdirectories']: + for external in json_data.get('external_subdirectories', []): external = pathlib.Path(external).resolve() if not external.is_dir(): logger.warn(f"External subdirectory {external} is invalid.") register(engine_path=engine_path, external_subdir_path=external, remove=True) - for template in json_data['templates']: + for template in json_data.get('templates', []): if not validation.valid_o3de_template_json(pathlib.Path(template).resolve() / 'template.json'): logger.warn(f"Template path {template} is invalid.") register(template_path=template, remove=True) - for restricted in json_data['restricted']: + for restricted in json_data.get('restricted', []): if not validation.valid_o3de_restricted_json(pathlib.Path(restricted).resolve() / 'restricted.json'): logger.warn(f"Restricted path {restricted} is invalid.") register(restricted_path=restricted, remove=True) - default_engines_folder = pathlib.Path(json_data['default_engines_folder']).resolve() + default_engines_folder = pathlib.Path(json_data.get('default_engines_folder', manifest.get_o3de_engines_folder())).resolve() if not default_engines_folder.is_dir(): new_default_engines_folder = manifest.get_o3de_folder() / 'Engines' new_default_engines_folder.mkdir(parents=True, exist_ok=True) @@ -714,7 +715,7 @@ def remove_invalid_o3de_objects() -> None: f"Default engines folder {default_engines_folder} is invalid. Set default {new_default_engines_folder}") register(default_engines_folder=new_default_engines_folder.as_posix()) - default_projects_folder = pathlib.Path(json_data['default_projects_folder']).resolve() + default_projects_folder = pathlib.Path(json_data.get('default_projects_folder', manifest.get_o3de_projects_folder())).resolve() if not default_projects_folder.is_dir(): new_default_projects_folder = manifest.get_o3de_folder() / 'Projects' new_default_projects_folder.mkdir(parents=True, exist_ok=True) @@ -722,7 +723,7 @@ def remove_invalid_o3de_objects() -> None: f"Default projects folder {default_projects_folder} is invalid. Set default {new_default_projects_folder}") register(default_projects_folder=new_default_projects_folder.as_posix()) - default_gems_folder = pathlib.Path(json_data['default_gems_folder']).resolve() + default_gems_folder = pathlib.Path(json_data.get('default_gems_folder', manifest.get_o3de_gems_folder())).resolve() if not default_gems_folder.is_dir(): new_default_gems_folder = manifest.get_o3de_folder() / 'Gems' new_default_gems_folder.mkdir(parents=True, exist_ok=True) @@ -730,7 +731,7 @@ def remove_invalid_o3de_objects() -> None: f" Set default {new_default_gems_folder}") register(default_gems_folder=new_default_gems_folder.as_posix()) - default_templates_folder = pathlib.Path(json_data['default_templates_folder']).resolve() + default_templates_folder = pathlib.Path(json_data.get('default_templates_folder', manifest.get_o3de_templates_folder())).resolve() if not default_templates_folder.is_dir(): new_default_templates_folder = manifest.get_o3de_folder() / 'Templates' new_default_templates_folder.mkdir(parents=True, exist_ok=True) @@ -739,7 +740,7 @@ def remove_invalid_o3de_objects() -> None: f" Set default {new_default_templates_folder}") register(default_templates_folder=new_default_templates_folder.as_posix()) - default_restricted_folder = pathlib.Path(json_data['default_restricted_folder']).resolve() + default_restricted_folder = pathlib.Path(json_data.get('default_restricted_folder', manifest.get_o3de_restricted_folder())).resolve() if not default_restricted_folder.is_dir(): default_restricted_folder = manifest.get_o3de_folder() / 'Restricted' default_restricted_folder.mkdir(parents=True, exist_ok=True) @@ -748,7 +749,7 @@ def remove_invalid_o3de_objects() -> None: f" Set default {default_restricted_folder}") register(default_restricted_folder=default_restricted_folder.as_posix()) - default_third_party_folder = pathlib.Path(json_data['default_third_party_folder']).resolve() + default_third_party_folder = pathlib.Path(json_data.get('default_third_party_folder', manifest.get_o3de_third_party_folder())).resolve() if not default_third_party_folder.is_dir(): default_third_party_folder = manifest.get_o3de_folder() / '3rdParty' default_third_party_folder.mkdir(parents=True, exist_ok=True)