From e8a65c0a92a5f7632c276a7fb2fb2fd11fc54048 Mon Sep 17 00:00:00 2001 From: Julian Rother <julian@jrother.eu> Date: Thu, 2 Dec 2021 18:05:28 +0100 Subject: [PATCH] DN parsing rewrite with REs --- ldapserver/dn.py | 48 ++++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/ldapserver/dn.py b/ldapserver/dn.py index b6ce3bf..f291fac 100644 --- a/ldapserver/dn.py +++ b/ldapserver/dn.py @@ -55,22 +55,16 @@ class DN(tuple): :raises ValueError: if expr is invalid :returns: Parsed DN :rtype: DN''' - escaped = False rdns = [] - token = '' - for char in expr: - if escaped: - escaped = False - token += char - elif char == ',': - rdns.append(RDN.from_str(schema, token)) - token = '' - else: - if char == '\\': - escaped = True - token += char - if token: - rdns.append(RDN.from_str(schema, token)) + while expr: + # relativeDistinguishedName may contain escape sequences including "\,". + # Split off first token expr at "," while ignoring "\,". + match = re.match(r'^(([^,\\]|\\.)+)(,|$)', expr) + if not match: + raise ValueError(f'Unrecognized token {expr!r}') + expr = expr[match.end():] + rdn_expr, _, _ = match.groups() + rdns.append(RDN.from_str(schema, rdn_expr)) return cls(schema, *rdns) def __str__(self): @@ -269,22 +263,16 @@ class RDN(tuple): :raises ValueError: if expr is invalid :returns: Parsed RDN :rtype: RDN''' - escaped = False assertions = [] - token = '' - for char in expr: - if escaped: - escaped = False - token += char - elif char == '+': - assertions.append(RDNAssertion.from_str(schema, token)) - token = '' - else: - if char == '\\': - escaped = True - token += char - if token: - assertions.append(RDNAssertion.from_str(schema, token)) + while expr: + # attributeTypeAndValue may contain escape sequences including "\+". + # Split off first token expr at "+" while ignoring "\+". + match = re.match(r'^(([^+\\]|\\.)+)(\+|$)', expr) + if not match: + raise ValueError(f'Unrecognized token {expr!r}') + expr = expr[match.end():] + assertion_expr, _, _ = match.groups() + assertions.append(RDNAssertion.from_str(schema, assertion_expr)) return cls(schema, *assertions) def __str__(self): -- GitLab