From 1d91ccf65980badc978def2c0214f6766d6c6842 Mon Sep 17 00:00:00 2001 From: Stefan Friesel Date: Tue, 17 Dec 2013 15:47:34 +0100 Subject: [PATCH] Redo "Parse env configuration in posix mode" Fixes #328 This allows (escaped) quotes in the values as well as empty values. This was done in pull request #329 but removed as it broke parsing empty quotes (#873) due to a bug in shlex (http://bugs.python.org/issue21999). This bug is fixed so posix mode can be used. Brings back #329 Partially reverts #880 --- CHANGES.rst | 3 +++ supervisor/datatypes.py | 4 ++-- supervisor/tests/test_datatypes.py | 5 +++++ 3 files changed, 10 insertions(+), 2 deletions(-) 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': ''}