diff --git a/CHANGES.rst b/CHANGES.rst index 27323b678..a1a443120 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -9,6 +9,9 @@ the ``[supervisorctl]`` section or ``[ctlplugin:x]`` sections to be in included files. Patch by François Granade. +- Parsing ``environment=`` has been improved to allow escaped quotes + inside quotes and quoted empty values. Patch by Stefan Friesel. + 4.2.5 (2022-12-23) ------------------ diff --git a/supervisor/datatypes.py b/supervisor/datatypes.py index 24932d95e..a67d0df9b 100644 --- a/supervisor/datatypes.py +++ b/supervisor/datatypes.py @@ -68,7 +68,7 @@ def dict_of_key_value_pairs(arg): """ parse KEY=val,KEY2=val2 into {'KEY':'val', 'KEY2':'val2'} Quotes can be used to allow commas in the value """ - lexer = shlex.shlex(str(arg)) + lexer = shlex.shlex(str(arg), posix=True) lexer.wordchars += '/.+-():' tokens = list(lexer) @@ -81,7 +81,7 @@ def dict_of_key_value_pairs(arg): if len(k_eq_v) != 3 or k_eq_v[1] != '=': raise ValueError( "Unexpected end of key/value pairs in value '%s'" % arg) - D[k_eq_v[0]] = k_eq_v[2].strip('\'"') + D[k_eq_v[0]] = k_eq_v[2] i += 4 return D diff --git a/supervisor/tests/test_datatypes.py b/supervisor/tests/test_datatypes.py index e2801310d..2e1a15b80 100644 --- a/supervisor/tests/test_datatypes.py +++ b/supervisor/tests/test_datatypes.py @@ -164,6 +164,11 @@ def test_handles_newlines_inside_quotes(self): expected = {'foo': 'a\nb\nc'} self.assertEqual(actual, expected) + def test_handles_quotes_inside_quotes(self): + actual = datatypes.dict_of_key_value_pairs('foo="\'\\""') + expected = {'foo': '\'"'} + self.assertEqual(actual, expected) + def test_handles_empty_inside_quotes(self): actual = datatypes.dict_of_key_value_pairs('foo=""') expected = {'foo': ''}