From ae6c8d2c7a65a85fe64a45b9430a91f9ab97e1d7 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Thu, 12 Apr 2018 11:47:00 -0400 Subject: [PATCH] Handle whitespace, add separator to regex in set_directive_lines We added the separator to the regex in set_directive_lines to avoid grabbing just a prefix. This doesn't allow for whitespace around the separator. For the Apache case we expected that the separator would be just spaces but it can also use tabs (like Ubuntu 18). Add a special case so that passing in a space separator is treated as whitespace (tab or space). https://pagure.io/freeipa/issue/7490 Signed-off-by: Rob Crittenden Reviewed-By: Florence Blanc-Renaud --- ipaserver/install/installutils.py | 10 ++++--- .../test_install/test_installutils.py | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index 6a7a19b31..fbec40efa 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -565,11 +565,15 @@ def set_directive_lines(quotes, separator, k, v, lines, comment): v_quoted = quote_directive_value(v, '"') if quotes else v new_line = ''.join([k, separator, v_quoted, '\n']) + # Special case: consider space as "white space" so tabs are allowed + if separator == ' ': + separator = '[ \t]+' + found = False addnext = False # add on next line, found a comment - matcher = re.compile(r'\s*{}'.format(re.escape(k + separator))) - cmatcher = re.compile(r'\s*{}\s*{}'.format(comment, - re.escape(k + separator))) + matcher = re.compile(r'\s*{}\s*{}'.format(re.escape(k), separator)) + cmatcher = re.compile(r'\s*{}\s*{}\s*{}'.format(comment, + re.escape(k), separator)) for line in lines: if matcher.match(line): found = True diff --git a/ipatests/test_ipaserver/test_install/test_installutils.py b/ipatests/test_ipaserver/test_install/test_installutils.py index 66b4585dd..0a426fe63 100644 --- a/ipatests/test_ipaserver/test_install/test_installutils.py +++ b/ipatests/test_ipaserver/test_install/test_installutils.py @@ -15,6 +15,11 @@ EXAMPLE_CONFIG = [ 'foobar=2\n', ] +WHITESPACE_CONFIG = [ + 'foo 1\n', + 'foobar\t2\n', +] + @pytest.fixture def tempdir(request): @@ -44,6 +49,28 @@ class test_set_directive_lines(object): assert list(lines) == ['foo=3\n', 'foobar=2\n'] +class test_set_directive_lines_whitespace(object): + def test_remove_directive(self): + lines = installutils.set_directive_lines( + False, ' ', 'foo', None, WHITESPACE_CONFIG, comment="#") + assert list(lines) == ['foobar\t2\n'] + + def test_add_directive(self): + lines = installutils.set_directive_lines( + False, ' ', 'baz', '4', WHITESPACE_CONFIG, comment="#") + assert list(lines) == ['foo 1\n', 'foobar\t2\n', 'baz 4\n'] + + def test_set_directive_does_not_clobber_suffix_key(self): + lines = installutils.set_directive_lines( + False, ' ', 'foo', '3', WHITESPACE_CONFIG, comment="#") + assert list(lines) == ['foo 3\n', 'foobar\t2\n'] + + def test_set_directive_with_tab(self): + lines = installutils.set_directive_lines( + False, ' ', 'foobar', '6', WHITESPACE_CONFIG, comment="#") + assert list(lines) == ['foo 1\n', 'foobar 6\n'] + + class test_set_directive(object): def test_set_directive(self): """Check that set_directive writes the new data and preserves mode."""