From e77d967b9e6a1d78af2eec3ecd85f592a212c43c Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 28 Nov 2011 19:49:00 +0100 Subject: rewrite parse_digest_response for escapes The previous version did not handle escapes at all. Now I added two test cases for escaping and rewrote the function to meet all test cases. --- wsgitools/digest.py | 62 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/wsgitools/digest.py b/wsgitools/digest.py index 53b7dea..964fa0a 100644 --- a/wsgitools/digest.py +++ b/wsgitools/digest.py @@ -60,28 +60,50 @@ def parse_digest_response(data, ret=None): ... except ValueError: ... print("ValueError") ValueError + >>> # backslashes: doc string, eval => two backslashes + >>> parse_digest_response('backslash="\\\\\\\\"') + {'backslash': '\\\\'} + >>> parse_digest_response('foo="quo\\\\"te"') + {'foo': 'quo"te'} """ assert isinstance(data, str) - if ret is None: - ret = {} - data = data.strip() - key, rest = data.split('=', 1) # raises ValueError - if rest.startswith('"'): - rest = rest[1:] - value, rest = rest.split('"', 1) # raises ValueError - if not rest: - ret[key] = value - return ret - if rest[0] != ',': - raise ValueError("invalid digest response") - rest = rest[1:] - else: - if ',' not in rest: - ret[key] = rest - return ret - value, rest = rest.split(',' , 1) - ret[key] = value - return parse_digest_response(rest, ret) + result = dict() + while True: + data = data.strip() + key, data = data.split('=', 1) # raises ValueError + if data.startswith('"'): + data = data[1:] + value = "" + while True: + part, data = data.split('"', 1) # raises ValueError + # how many consecutive backslashes did we see? + escape = -1 # the first iteration does not indicate a backslash + for part in part.split('\\'): + escape += 1 # backslash before part + if escape > 2: + value += "\\" + escape -= 2 + if part: + escape = 0 + value += part + if escape == 2: + value += "\\" + elif escape == 1: + value += '"' + continue + break + result[key] = value + if not data: + return result + if data[0] != ",": + raise ValueError("invalid digest response") + data = data[1:] + else: + if ',' not in data: + result[key] = data + return result + value, data = data.split(',', 1) + result[key] = value class AuthenticationRequired(Exception): """ -- cgit v1.2.3