From 0eebd5cef982686b9438b35d4c4ed395f437ff3e Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Fri, 25 Oct 2002 21:52:00 +0000 Subject: Implement a safer and more predictable interpolation approach. Closes SF bug #511737. --- Lib/ConfigParser.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'Lib/ConfigParser.py') diff --git a/Lib/ConfigParser.py b/Lib/ConfigParser.py index c623ec999f..607702294b 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 '('") -- cgit v1.2.1