diff options
author | Fred Drake <fdrake@acm.org> | 2002-10-25 21:52:00 (GMT) |
---|---|---|
committer | Fred Drake <fdrake@acm.org> | 2002-10-25 21:52:00 (GMT) |
commit | 0eebd5cef982686b9438b35d4c4ed395f437ff3e (patch) | |
tree | 49c7affd13defeba3e18990e2a9818fd83482aee /Lib/ConfigParser.py | |
parent | 98e3b29b5969b7738c4c2e1e21fea47357ea6aa0 (diff) | |
download | cpython-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.py | 48 |
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 '('") |