RF+BF+ENH: Rewrite extract options, and now allow "=" char in options

pull/224/head
Steven Hiscocks 2013-05-10 17:24:23 +01:00
parent 970291867b
commit 33a7763cfc
2 changed files with 15 additions and 46 deletions

View File

@ -36,6 +36,8 @@ logSys = logging.getLogger(__name__)
class JailReader(ConfigReader):
optionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$")
optionExtractRE = re.compile(
r'([\w\-_\.]+)=(?:"([^"]*)"|\'([^\']*)\'|([^,]*))(?:,|$)')
def __init__(self, name, force_enable=False, **kwargs):
ConfigReader.__init__(self, **kwargs)
@ -155,46 +157,13 @@ class JailReader(ConfigReader):
#@staticmethod
def extractOptions(option):
m = JailReader.optionCRE.match(option)
d = dict()
mgroups = m.groups()
if len(mgroups) == 2:
option_name, option_opts = mgroups
elif len(mgroups) == 1:
option_name, option_opts = mgroups[0], None
else:
raise ValueError("While reading option %s we should have got up to "
"2 groups. Got: %r" % (option, mgroups))
if not option_opts is None:
# Huge bad hack :( This method really sucks. TODO Reimplement it.
options = ""
escapeChar = None
allowComma = False
for c in option_opts:
if c in ('"', "'") and not allowComma:
# Start
escapeChar = c
allowComma = True
elif c == escapeChar:
# End
escapeChar = None
allowComma = False
else:
if c == ',' and allowComma:
options += "<COMMA>"
else:
options += c
# Split using ,
optionsSplit = options.split(',')
# Replace the tag <COMMA> with ,
optionsSplit = [n.replace("<COMMA>", ',') for n in optionsSplit]
for param in optionsSplit:
p = param.split('=')
try:
d[p[0].strip()] = p[1].strip()
except IndexError:
logSys.error("Invalid argument %s in '%s'" % (p, option_opts))
return [option_name, d]
option_name, optstr = JailReader.optionCRE.match(option).groups()
option_opts = dict()
if optstr:
for optmatch in JailReader.optionExtractRE.finditer(optstr):
opt = optmatch.group(1)
value = [
val for val in optmatch.group(2,3,4) if val is not None][0]
option_opts[opt.strip()] = value.strip()
return option_name, option_opts
extractOptions = staticmethod(extractOptions)

View File

@ -147,19 +147,19 @@ class JailReaderTest(unittest.TestCase):
def testSplitOption(self):
# Simple example
option = "mail-whois[name=SSH]"
expected = ['mail-whois', {'name': 'SSH'}]
expected = ('mail-whois', {'name': 'SSH'})
result = JailReader.extractOptions(option)
self.assertEqual(expected, result)
# Empty option
option = "abc[]"
expected = ['abc', {}]
expected = ('abc', {})
result = JailReader.extractOptions(option)
self.assertEqual(expected, result)
# More complex examples
option = 'option[opt01=abc,opt02="123",opt03="with=okay?",opt04="andwith,okay...",opt05="how about spaces",opt06="single\'in\'double",opt07=\'double"in"single\', opt08= leave some space, opt09=one for luck, opt10=, opt11=]'
expected = ['option', {
expected = ('option', {
'opt01': "abc",
'opt02': "123",
'opt03': "with=okay?",
@ -171,7 +171,7 @@ class JailReaderTest(unittest.TestCase):
'opt09': "one for luck",
'opt10': "",
'opt11': "",
}]
})
result = JailReader.extractOptions(option)
self.assertEqual(expected, result)