commit:     05961fe814decbac02755e95aba50a9f4e104d7e
Author:     Felix Bier <flx.bier <AT> gmail <DOT> com>
AuthorDate: Tue May 18 23:05:40 2021 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon May 24 06:19:09 2021 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=05961fe8

Change _shell_quote to handle more special characters

This commit changes the function _shell_quote to ensure more
special characters are quoted correctly.

Without this commit, the following error message occurs when attempting
to merge an ebuild that inherits from an eclass contained in a
repository located in a filesystem path containing special characters:

.../ebuild.sh: eval: line 604: syntax error near unexpected token `('
.../ebuild.sh: eval: line 604: `PORTAGE_ECLASS_LOCATIONS=(/var/db/repos/gentoo 
/home/user/test(v2)/test-overlay)'

The paths that are handled in that line were sanitized with _shell_quote
beforehand, but the list of special characters handled by _shell_quote
did not include (). For this reason, the list has been extended to
handle the following special characters that were not handled before:

;&|(){}[]#!~?

Closes: https://github.com/gentoo/portage/pull/719
Signed-off-by: Felix Bier <felix.bier <AT> rohde-schwarz.com>
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/portage/__init__.py                      |  2 +-
 lib/portage/tests/ebuild/test_shell_quote.py | 47 ++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/lib/portage/__init__.py b/lib/portage/__init__.py
index 7659be995..6e22a174b 100644
--- a/lib/portage/__init__.py
+++ b/lib/portage/__init__.py
@@ -403,7 +403,7 @@ def _get_stdin():
                return sys.__stdin__
        return sys.stdin
 
-_shell_quote_re = re.compile(r"[\s><=*\\\"'$`]")
+_shell_quote_re = re.compile(r"[\s><=*\\\"'$`;&|(){}\[\]#!~?]")
 
 def _shell_quote(s):
        """

diff --git a/lib/portage/tests/ebuild/test_shell_quote.py 
b/lib/portage/tests/ebuild/test_shell_quote.py
index ce419488a..6d4553518 100644
--- a/lib/portage/tests/ebuild/test_shell_quote.py
+++ b/lib/portage/tests/ebuild/test_shell_quote.py
@@ -72,6 +72,53 @@ class ShellQuoteTestCase(TestCase):
                        ("abc''xyz","\"abc''xyz\""),
                        ("'abcxyz'","\"'abcxyz'\""),
 
+                       # String contains ;, should be double-quoted to prevent 
command separation.
+                       ("abc;xyz","\"abc;xyz\""),
+                       ("abc;;xyz","\"abc;;xyz\""),
+                       (";abcxyz;","\";abcxyz;\""),
+
+                       # String contains &, should be double-quoted to prevent 
job control.
+                       ("abc&xyz","\"abc&xyz\""),
+                       ("abc&&xyz","\"abc&&xyz\""),
+                       ("&abcxyz&","\"&abcxyz&\""),
+
+                       # String contains |, should be double-quoted to prevent 
piping.
+                       ("abc|xyz","\"abc|xyz\""),
+                       ("abc||xyz","\"abc||xyz\""),
+                       ("|abcxyz|","\"|abcxyz|\""),
+
+                       # String contains (), should be double-quoted to prevent
+                       # command group / array initialization.
+                       ("abc()xyz","\"abc()xyz\""),
+                       ("abc(())xyz","\"abc(())xyz\""),
+                       ("((abcxyz))","\"((abcxyz))\""),
+
+                       # String contains {}. Parameter expansion of the form 
${} is already
+                       # rendered safe by escaping the $, but {} could also 
occur on its own,
+                       # for example in a brace expansion such as 
filename.{ext1,ext2},
+                       # so the string should be double-quoted.
+                       ("abc{}xyz","\"abc{}xyz\""),
+                       ("abc{{}}xyz","\"abc{{}}xyz\""),
+                       ("{{abcxyz}}","\"{{abcxyz}}\""),
+
+                       # String contains [], should be double-quoted to 
prevent testing
+                       ("abc[]xyz","\"abc[]xyz\""),
+                       ("abc[[]]xyz","\"abc[[]]xyz\""),
+                       ("[[abcxyz]]","\"[[abcxyz]]\""),
+
+                       # String contains #, should be double-quoted to prevent 
comment.
+                       ("#abc","\"#abc\""),
+
+                       # String contains !, should be double-quoted to prevent 
e.g. history substitution.
+                       ("!abc","\"!abc\""),
+
+                       # String contains ~, should be double-quoted to prevent 
home directory expansion.
+                       ("~abc","\"~abc\""),
+
+                       # String contains ?, should be double-quoted to prevent 
globbing.
+                       ("abc?xyz","\"abc?xyz\""),
+                       ("abc??xyz","\"abc??xyz\""),
+                       ("?abcxyz?","\"?abcxyz?\""),
                ]
 
                for (data,expected_result) in test_data:

Reply via email to