diff --git a/src/west/manifest.py b/src/west/manifest.py index 0f8a3ed5..a6e0797e 100644 --- a/src/west/manifest.py +++ b/src/west/manifest.py @@ -33,6 +33,9 @@ '''Names of the special "meta-projects", which are reserved and cannot be used to name a project in the manifest file.''' +WEST_RESTRICTED_FOLDERS = ['west'] +'''Restricted folders that are used by "west" itself for "meta-projects"''' + MANIFEST_SECTIONS = ['manifest', 'west'] '''Sections in the manifest file''' @@ -216,6 +219,15 @@ def _load(self, data, sections): format(name) + 'be used to name a manifest project') + path = mp.get('path') + if path is not None: + path = os.path.normpath(path) + for restricted_path in WEST_RESTRICTED_FOLDERS: + if os.path.commonpath([restricted_path, path]): + self._malformed('the folder "{}" is restricted and '. + format(restricted_path) + + 'cannot be used for local projects') + # Validate the project remote. remote_name = mp.get('remote', default_remote_name) if remote_name is None: @@ -227,7 +239,7 @@ def _load(self, data, sections): project = Project(name, remotes_dict[remote_name], defaults, - path=mp.get('path'), + path=path, clone_depth=mp.get('clone-depth'), revision=mp.get('revision')) diff --git a/tests/west/manifest/invalid_restricted_project_normalized_path.yml b/tests/west/manifest/invalid_restricted_project_normalized_path.yml new file mode 100644 index 00000000..b3dd1c2c --- /dev/null +++ b/tests/west/manifest/invalid_restricted_project_normalized_path.yml @@ -0,0 +1,11 @@ +manifest: + defaults: + remote: testremote + + remotes: + - name: testremote + url-base: https://example.com + + projects: + - name: foo1 + path: foo/../west diff --git a/tests/west/manifest/invalid_restricted_project_path.yml b/tests/west/manifest/invalid_restricted_project_path.yml new file mode 100644 index 00000000..9b04496d --- /dev/null +++ b/tests/west/manifest/invalid_restricted_project_path.yml @@ -0,0 +1,11 @@ +manifest: + defaults: + remote: testremote + + remotes: + - name: testremote + url-base: https://example.com + + projects: + - name: foo1 + path: west diff --git a/tests/west/manifest/invalid_restricted_project_sub_path.yml b/tests/west/manifest/invalid_restricted_project_sub_path.yml new file mode 100644 index 00000000..b62409fc --- /dev/null +++ b/tests/west/manifest/invalid_restricted_project_sub_path.yml @@ -0,0 +1,11 @@ +manifest: + defaults: + remote: testremote + + remotes: + - name: testremote + url-base: https://example.com + + projects: + - name: foo1 + path: west/foo diff --git a/tests/west/manifest/test_manifest.py b/tests/west/manifest/test_manifest.py index c7c5c7d8..750acbb9 100644 --- a/tests/west/manifest/test_manifest.py +++ b/tests/west/manifest/test_manifest.py @@ -127,6 +127,29 @@ def test_path(): assert manifest.projects[0].path == 'sub/directory' assert manifest.projects[0].abspath == os.path.realpath('/west_top/sub/directory') +def test_restricted_path(): + # Projects are restricted from west/ folder, but folders containing west as + # part of path name, e.g. west-ext arte still allowed. + content = '''\ + manifest: + remotes: + - name: testremote + url-base: https://example.com + projects: + - name: testproject + remote: testremote + path: west-ext + - name: testsubproject + remote: testremote + path: west-ext/sub + ''' + with patch('west.util.west_topdir', return_value=os.path.realpath('/west_top')): + manifest = Manifest.from_data(yaml.safe_load(content)) + assert manifest.projects[0].path == 'west-ext' + assert manifest.projects[0].abspath == os.path.realpath('/west_top/west-ext') + assert manifest.projects[1].path == 'west-ext/sub' + assert manifest.projects[1].abspath == os.path.realpath('/west_top/west-ext/sub') + def test_sections(): # Projects must be able to override their default paths. content_wrong_west = '''\