summaryrefslogtreecommitdiffstats
path: root/Lib/ConfigParser.py
diff options
context:
space:
mode:
authorFred Drake <fdrake@acm.org>2002-10-25 21:52:00 (GMT)
committerFred Drake <fdrake@acm.org>2002-10-25 21:52:00 (GMT)
commit0eebd5cef982686b9438b35d4c4ed395f437ff3e (patch)
tree49c7affd13defeba3e18990e2a9818fd83482aee /Lib/ConfigParser.py
parent98e3b29b5969b7738c4c2e1e21fea47357ea6aa0 (diff)
downloadcpython-0eebd5cef982686b9438b35d4c4ed395f437ff3e.zip
cpython-0eebd5cef982686b9438b35d4c4ed395f437ff3e.tar.gz
cpython-0eebd5cef982686b9438b35d4c4ed395f437ff3e.tar.bz2
Implement a safer and more predictable interpolation approach.
Closes SF bug #511737.
Diffstat (limited to 'Lib/ConfigParser.py')
-rw-r--r--Lib/ConfigParser.py48
1 files changed, 48 insertions, 0 deletions
diff --git a/Lib/ConfigParser.py b/Lib/ConfigParser.py
index c623ec9..6077022 100644
--- a/Lib/ConfigParser.py
+++ b/Lib/ConfigParser.py
@@ -538,3 +538,51 @@ class ConfigParser(RawConfigParser):
if value.find("%(") != -1:
raise InterpolationDepthError(option, section, rawval)
return value
+
+
+class SafeConfigParser(ConfigParser):
+
+ def _interpolate(self, section, option, rawval, vars):
+ # do the string interpolation
+ L = []
+ self._interpolate_some(option, L, rawval, section, vars, 1)
+ return ''.join(L)
+
+ _interpvar_match = re.compile(r"%\(([^)]+)\)s").match
+
+ def _interpolate_some(self, option, accum, rest, section, map, depth):
+ if depth > MAX_INTERPOLATION_DEPTH:
+ raise InterpolationDepthError(option, section, rest)
+ while rest:
+ p = rest.find("%")
+ if p < 0:
+ accum.append(rest)
+ return
+ if p > 0:
+ accum.append(rest[:p])
+ rest = rest[p:]
+ # p is no longer used
+ c = rest[1:2]
+ if c == "%":
+ accum.append("%")
+ rest = rest[2:]
+ elif c == "(":
+ m = self._interpvar_match(rest)
+ if m is None:
+ raise InterpolationSyntaxError(
+ "bad interpolation variable syntax at: %r" % rest)
+ var = m.group(1)
+ rest = rest[m.end():]
+ try:
+ v = map[var]
+ except KeyError:
+ raise InterpolationError(
+ "no value found for %r" % var)
+ if "%" in v:
+ self._interpolate_some(option, accum, v,
+ section, map, depth + 1)
+ else:
+ accum.append(v)
+ else:
+ raise InterpolationSyntaxError(
+ "'%' must be followed by '%' or '('")