ipa/0038-get_directive-don-t-er...

121 lines
4.6 KiB
Diff

From 95b066d629de935bfb52e732ce52026e18e9c64d Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Wed, 10 Jan 2024 16:45:12 -0500
Subject: [PATCH] get_directive: don't error out on substring mismatch
This function is designed to retrieve a value from an
ini-like file. In particular PKI CS.cfg.
In an attempt to be more efficient a substring search,
using startswith(), is used before calling a regular
expression match.
The problem is that if the requested directive is a
substring of a different one then it will pass the
startswith() and fail the regular expression match
with a ValueError, assuming it is malformed.
There is no need for this. The caller must be able to
handle None as a response anyway. So continue if
no match is found.
This was seen when PKI dropped storing certificate blobs
in CS.cfg. The CA certificate is stored in ca.signing.cert.
If it isn't present then ca.signing.certnickname will match
the substring but not the directive. This should not be
treated as an error.
Fixes: https://pagure.io/freeipa/issue/9506
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipapython/directivesetter.py | 5 ++-
.../test_ipapython/test_directivesetter.py | 33 +++++++++++++++++++
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/ipapython/directivesetter.py b/ipapython/directivesetter.py
index f4e496c7f0f785a909bfb5b8196582fb5dd865ea..732e1c239ca375e6ec08882e4731f97cb1ff58a9 100644
--- a/ipapython/directivesetter.py
+++ b/ipapython/directivesetter.py
@@ -182,6 +182,9 @@ def get_directive(filename, directive, separator=' '):
if separator == ' ':
separator = '[ \t]+'
+ if directive is None:
+ return None
+
result = None
with open(filename, "r") as fd:
for line in fd:
@@ -193,7 +196,7 @@ def get_directive(filename, directive, separator=' '):
if match:
value = match.group(1)
else:
- raise ValueError("Malformed directive: {}".format(line))
+ continue
result = unquote_directive_value(value.strip(), '"')
result = result.strip(' ')
diff --git a/ipatests/test_ipapython/test_directivesetter.py b/ipatests/test_ipapython/test_directivesetter.py
index 08a30124b12c3bd8edf8fa7930377faf7b181f5d..ff86559e0a3eb018e4a26a489c190a0da380ce1f 100644
--- a/ipatests/test_ipapython/test_directivesetter.py
+++ b/ipatests/test_ipapython/test_directivesetter.py
@@ -18,6 +18,10 @@ WHITESPACE_CONFIG = [
'foobar\t2\n',
]
+SUBSTRING_CONFIG = [
+ 'foobar=2\n',
+]
+
class test_set_directive_lines:
def test_remove_directive(self):
@@ -88,6 +92,7 @@ class test_set_directive:
class test_get_directive:
def test_get_directive(self, tmpdir):
+ """Test retrieving known values from a config file"""
configfile = tmpdir.join('config')
configfile.write(''.join(EXAMPLE_CONFIG))
@@ -97,6 +102,34 @@ class test_get_directive:
assert '2' == directivesetter.get_directive(str(configfile),
'foobar',
separator='=')
+ assert None is directivesetter.get_directive(str(configfile),
+ 'notfound',
+ separator='=')
+
+ def test_get_directive_substring(self, tmpdir):
+ """Test retrieving values from a config file where there is
+ a similar substring that is not present.
+ """
+ configfile = tmpdir.join('config')
+ configfile.write(''.join(SUBSTRING_CONFIG))
+
+ assert None is directivesetter.get_directive(str(configfile),
+ 'foo',
+ separator='=')
+ assert '2' == directivesetter.get_directive(str(configfile),
+ 'foobar',
+ separator='=')
+
+ def test_get_directive_none(self, tmpdir):
+ """Test retrieving a value from a config file where the
+ directive is None. i.e. don't fail.
+ """
+ configfile = tmpdir.join('config')
+ configfile.write(''.join(EXAMPLE_CONFIG))
+
+ assert None is directivesetter.get_directive(str(configfile),
+ None,
+ separator='=')
class test_get_directive_whitespace:
--
2.43.0