blob: 6d4553518c05162f1471df8f7a31317f89a363e5 [file] [log] [blame]
# Copyright 2021 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from portage import _shell_quote
from portage.tests import TestCase
class ShellQuoteTestCase(TestCase):
def testShellQuote(self):
test_data = [
# String contains no special characters, should be preserved.
("abc","abc"),
# String contains whitespace, should be double-quoted to prevent word splitting.
("abc xyz","\"abc xyz\""),
("abc xyz","\"abc xyz\""),
(" abcxyz ","\" abcxyz \""),
("abc\txyz","\"abc\txyz\""),
("abc\t\txyz","\"abc\t\txyz\""),
("\tabcxyz\t","\"\tabcxyz\t\""),
("abc\nxyz","\"abc\nxyz\""),
("abc\n\nxyz","\"abc\n\nxyz\""),
("\nabcxyz\n","\"\nabcxyz\n\""),
# String contains > or <, should be double-quoted to prevent redirection.
("abc>xyz","\"abc>xyz\""),
("abc>>xyz","\"abc>>xyz\""),
(">abcxyz>","\">abcxyz>\""),
("abc<xyz","\"abc<xyz\""),
("abc<<xyz","\"abc<<xyz\""),
("<abcxyz<","\"<abcxyz<\""),
# String contains =, should be double-quoted to prevent assignment.
("abc=xyz","\"abc=xyz\""),
("abc==xyz","\"abc==xyz\""),
("=abcxyz=","\"=abcxyz=\""),
# String contains *, should be double-quoted to prevent globbing.
("abc*xyz","\"abc*xyz\""),
("abc**xyz","\"abc**xyz\""),
("*abcxyz*","\"*abcxyz*\""),
# String contains $, should be escaped to prevent parameter expansion.
# Also double-quoted, though not strictly needed.
("abc$xyz","\"abc\\$xyz\""),
("abc$$xyz","\"abc\\$\\$xyz\""),
("$abcxyz$","\"\\$abcxyz\\$\""),
# String contains `, should be escaped to prevent command substitution.
# Also double-quoted, though not strictly needed.
("abc`xyz","\"abc\\`xyz\""),
("abc``xyz","\"abc\\`\\`xyz\""),
("`abc`","\"\\`abc\\`\""),
# String contains \, should be escaped to prevent it from escaping
# the next character. Also double-quoted, though not strictly needed.
("abc\\xyz", "\"abc\\\\xyz\""),
("abc\\\\xyz", "\"abc\\\\\\\\xyz\""),
("\\abcxyz\\", "\"\\\\abcxyz\\\\\""),
# String contains ", should be escaped to prevent it from unexpectedly
# ending a previous double-quote or starting a new double-quote. Also
# double-quoted, though not strictly needed.
("abc\"xyz","\"abc\\\"xyz\""),
("abc\"\"xyz","\"abc\\\"\\\"xyz\""),
("\"abcxyz\"","\"\\\"abcxyz\\\"\""),
# String contains ', should be double-quoted to prevent it from unexpectedly
# ending a previous single-quote or starting a new single-quote.
("abc'xyz","\"abc'xyz\""),
("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:
result = _shell_quote(data)
self.assertEqual(result, expected_result)