Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

west cannot process a git branch name containing a single quote ' #679

Closed
GarrettCarter-eaton opened this issue Aug 30, 2023 · 8 comments
Closed
Labels
bug Something isn't working priority: medium

Comments

@GarrettCarter-eaton
Copy link

If a repo that west clones and processes contains a branch name using a single quote, the following error is received:

Traceback (most recent call last):
  File "/usr/local/bin/west", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.8/dist-packages/west/app/main.py", line 793, in main
    app.run(argv or sys.argv[1:])
  File "/usr/local/lib/python3.8/dist-packages/west/app/main.py", line 109, in run
    self.run_command(argv)
  File "/usr/local/lib/python3.8/dist-packages/west/app/main.py", line 342, in run_command
    cmd.run(args, unknown, self.topdir, manifest=self.manifest,
  File "/usr/local/lib/python3.8/dist-packages/west/commands.py", line 135, in run
    self.do_run(args, unknown)
  File "/usr/local/lib/python3.8/dist-packages/west/app/project.py", line 806, in do_run
    self.update_all()
  File "/usr/local/lib/python3.8/dist-packages/west/app/project.py", line 871, in update_all
    self.update(project)
  File "/usr/local/lib/python3.8/dist-packages/west/app/project.py", line 1039, in update
    self.clean_refs_west(project, stats, take_stats)
  File "/usr/local/lib/python3.8/dist-packages/west/app/project.py", line 1296, in clean_refs_west
    _clean_west_refspace(project)
  File "/usr/local/lib/python3.8/dist-packages/west/app/project.py", line 1471, in _clean_west_refspace
    project.git(delete_ref_cmd)
  File "/usr/local/lib/python3.8/dist-packages/west/manifest.py", line 807, in git
    cmd_list = shlex.split(cmd)
  File "/usr/lib/python3.8/shlex.py", line 311, in split
    return list(lex)
  File "/usr/lib/python3.8/shlex.py", line 300, in __next__
    token = self.get_token()
  File "/usr/lib/python3.8/shlex.py", line 109, in get_token
    raw = self.read_token()
  File "/usr/lib/python3.8/shlex.py", line 191, in read_token
    raise ValueError("No closing quotation")
ValueError: No closing quotation

Example branch name:
LTK-18338-No-link-for-privacy-policy-on-WebUI's-Login-page

@marc-hb
Copy link
Collaborator

marc-hb commented Aug 30, 2023

Thanks for the report!

I think I know what's happening and how to fix it but this looks tedious to reproduce because the quote must be in a remote branch, not just in a local branch.

Can you share a public manifest/repo that reproduces? A small one if possible.

@marc-hb marc-hb added bug Something isn't working priority: medium labels Aug 30, 2023
@mbolivar-ampere
Copy link
Collaborator

Can you share a public manifest/repo that reproduces? A small one if possible.

https://github.com/mbolivar-ampere/west/tree/test-'-for-marc

@marc-hb
Copy link
Collaborator

marc-hb commented Aug 31, 2023

Thanks @mbolivar-ampere . I still cannot reproduce, probably because the management of refs/west/* has changed.

@GarrettCarter-eaton which west version are you using? Please look at this bug template for "inspiration": https://github.com/zephyrproject-rtos/zephyr/issues/new?assignees=&labels=bug&projects=&template=001_bug_report.md&title=

@GarrettCarter-eaton
Copy link
Author

GarrettCarter-eaton commented Sep 1, 2023

To Reproduce
Manifest repo: https://github.com/GarrettCarter-eaton/west-quote-test-manifest
Dependency of manifest repo (containing quote in a branch name): https://github.com/GarrettCarter-eaton/west-quote-test-dep

  1. west init -m https://github.com/GarrettCarter-eaton/west-quote-test-manifest
  2. west update
  3. See error

I'm noticing the behavior differs depending on what revision of the dependency repo you specify. When I specify a git SHA, West seems to process all the refs in the repo which leads to the quote processing failure.

Expected behavior
Expect west update to complete without failure. A single quote is a valid character in a git branch name in most systems.

Impact
Cannot complete the west update, leaving my dependency tree incomplete.

Logs and console output

PS C:\west-quote-test> west init -m https://github.com/GarrettCarter-eaton/west-quote-test-manifest
=== Initializing in C:\west-quote-test
--- Cloning manifest repository from https://github.com/GarrettCarter-eaton/west-quote-test-manifest
Cloning into 'C:\west-quote-test\.west\manifest-tmp'...
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 15 (delta 4), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (15/15), done.
Resolving deltas: 100% (4/4), done.
--- setting manifest.path to west-quote-test-manifest
=== Initialized. Now run "west update" inside C:\west-quote-test.
PS C:\west-quote-test> west update
=== updating west-quote-test-dep (west-quote-test-dep):
--- west-quote-test-dep: initializing
Initialized empty Git repository in C:/west-quote-test/west-quote-test-dep/.git/
--- west-quote-test-dep: fetching, need revision bb4143e
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 9 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (9/9), 1.93 KiB | 86.00 KiB/s, done.
From https://github.com/GarrettCarter-eaton/west-quote-test-dep
 * [new branch]      branch-with-'-quote -> refs/west/branch-with-'-quote
 * [new branch]      main                -> refs/west/main
 * [new branch]      other-rev           -> refs/west/other-rev
Traceback (most recent call last):
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\Scripts\west.exe\__main__.py", line 7, in <module>
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\app\main.py", line 866, in main
    app.run(argv or sys.argv[1:])
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\app\main.py", line 111, in run
    self.run_command(argv)
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\app\main.py", line 383, in run_command
    self.run_builtin(args, unknown)
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\app\main.py", line 424, in run_builtin
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\commands.py", line 194, in run
    self.do_run(args, unknown)
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\app\project.py", line 823, in do_run
    self.update_all()
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\app\project.py", line 888, in update_all
    self.update(project)
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\app\project.py", line 1062, in update
    self.clean_refs_west(project, stats, take_stats)
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\app\project.py", line 1350, in clean_refs_west
    _clean_west_refspace(project)
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\app\project.py", line 1524, in _clean_west_refspace
    project.git(delete_ref_cmd)
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\site-packages\west\manifest.py", line 807, in git
    cmd_list = shlex.split(cmd)
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\shlex.py", line 315, in split
    return list(lex)
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\shlex.py", line 300, in __next__
    token = self.get_token()
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\shlex.py", line 109, in get_token
    raw = self.read_token()
  File "C:\Users\eXXXXXXX\AppData\Local\Programs\Python\Python310\lib\shlex.py", line 191, in read_token
    raise ValueError("No closing quotation")
ValueError: No closing quotation
PS C:\west-quote-test> west -V
West version: v1.0.0
PS C:\west-quote-test>

Environment

  • OS: Windows
  • Toolchain: Zephyr SDK
  • West 1.0.0

marc-hb added a commit to marc-hb/west that referenced this issue Sep 1, 2023
For convenience, Project.git() supports passing either a list (good) or
a string with whitespaces (bad). The latter is parsed with shlex.split()

This saves some typing but the caller has to be extremely careful to
never use the shlex.split() convenience with unsanitized inputs.

Fixes commit 3ac600a ("git: clean west ref space after fetching")
where the caller was not careful and concatenated `update-ref -d ` with
unsanitized input, possibly containing special characters as found in
bug zephyrproject-rtos#679. Fix this bug by converting the string to a list.

While at it, look for a few other, frequent and risky invocations and
convert their string argument to a list too. The following test hack was
used to semi-automate the search for these other locations:

```
--- a/src/west/manifest.py
+++ b/src/west/manifest.py
@@ -897,6 +897,8 @@ class Project:
         :param cwd: directory to run git in (default: ``self.abspath``)
         '''
         if isinstance(cmd, str):
+            print(cmd)
+            breakpoint()
             cmd_list = shlex.split(cmd)
         else:
             cmd_list = list(cmd)
```

While at it, also convert to a list a couple non-risky but very frequent
invocations. This speeds up the test hack above.

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
marc-hb added a commit to marc-hb/west that referenced this issue Sep 1, 2023
For convenience, Project.git() supports passing either a list (good) or
a string with whitespaces (bad). The latter is parsed with shlex.split()

This saves some typing but the caller has to be extremely careful to
never use the shlex.split() convenience with unsanitized inputs.

Fixes commit 3ac600a ("git: clean west ref space after fetching")
where the caller was not careful and concatenated `update-ref -d ` with
unsanitized input, possibly containing special characters as found in
bug zephyrproject-rtos#679. Fix this bug by converting the string to a list.

While at it, look for a few other, frequent and risky invocations and
convert their string argument to a list too. The following test hack was
used to semi-automate the search for these other locations:

```
--- a/src/west/manifest.py
+++ b/src/west/manifest.py
@@ -897,6 +897,8 @@ class Project:
         :param cwd: directory to run git in (default: ``self.abspath``)
         '''
         if isinstance(cmd, str):
+            print(cmd)
+            breakpoint()
             cmd_list = shlex.split(cmd)
         else:
             cmd_list = list(cmd)
```

While at it, also convert to a list a couple non-risky but very frequent
invocations. This speeds up the test hack above.

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
@marc-hb
Copy link
Collaborator

marc-hb commented Sep 1, 2023

Thanks @GarrettCarter-eaton for the test case, it really saved my time. Fix submitted in #683, would you be in a position to test it? Check the west/README.txt for installing directly from source. If you go and do that, do pip uninstall west first.

marc-hb added a commit to marc-hb/west that referenced this issue Sep 1, 2023
For convenience, Project.git() supports passing either a list (good) or
a string with whitespaces (bad). The latter is parsed with shlex.split()

This saves some typing but the caller has to be extremely careful to
never use the shlex.split() convenience with unsanitized inputs.

Fixes commit 3ac600a ("git: clean west ref space after fetching")
where the caller was not careful and concatenated `update-ref -d ` with
unsanitized input, possibly containing special characters as found in
bug zephyrproject-rtos#679. Fix this bug by converting the string to a list.

While at it, look for a few other, frequent and risky invocations and
convert their string argument to a list too. The following test hack was
used to semi-automate the search for these other locations:

```
--- a/src/west/manifest.py
+++ b/src/west/manifest.py
@@ -897,6 +897,8 @@ class Project:
         :param cwd: directory to run git in (default: ``self.abspath``)
         '''
         if isinstance(cmd, str):
+            print(cmd)
+            breakpoint()
             cmd_list = shlex.split(cmd)
         else:
             cmd_list = list(cmd)
```

While at it, also convert to a list a couple non-risky but very frequent
invocations. This speeds up the test hack above.

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
mbolivar-ampere pushed a commit that referenced this issue Sep 1, 2023
For convenience, Project.git() supports passing either a list (good) or
a string with whitespaces (bad). The latter is parsed with shlex.split()

This saves some typing but the caller has to be extremely careful to
never use the shlex.split() convenience with unsanitized inputs.

Fixes commit 3ac600a ("git: clean west ref space after fetching")
where the caller was not careful and concatenated `update-ref -d ` with
unsanitized input, possibly containing special characters as found in
bug #679. Fix this bug by converting the string to a list.

While at it, look for a few other, frequent and risky invocations and
convert their string argument to a list too. The following test hack was
used to semi-automate the search for these other locations:

```
--- a/src/west/manifest.py
+++ b/src/west/manifest.py
@@ -897,6 +897,8 @@ class Project:
         :param cwd: directory to run git in (default: ``self.abspath``)
         '''
         if isinstance(cmd, str):
+            print(cmd)
+            breakpoint()
             cmd_list = shlex.split(cmd)
         else:
             cmd_list = list(cmd)
```

While at it, also convert to a list a couple non-risky but very frequent
invocations. This speeds up the test hack above.

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
@marc-hb
Copy link
Collaborator

marc-hb commented Sep 8, 2023

Please re-open if not fixed by #683

@marc-hb marc-hb closed this as completed Sep 8, 2023
@laurensmiers
Copy link

Just FYI, tested with c936a4a and issue is fixed.

@GarrettCarter-eaton
Copy link
Author

I can confirm that this bug is resolved in the v1.2.0 release of West.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working priority: medium
Projects
None yet
Development

No branches or pull requests

4 participants