Forking what is left of ZeroNet and hopefully adding an AT Proto Frontend/Proxy
1import re
2
3
4class UnsafePatternError(Exception):
5 pass
6
7cached_patterns = {}
8
9
10def isSafePattern(pattern):
11 if len(pattern) > 255:
12 raise UnsafePatternError("Pattern too long: %s characters in %s" % (len(pattern), pattern))
13
14 unsafe_pattern_match = re.search(r"[^\.][\*\{\+]", pattern) # Always should be "." before "*{+" characters to avoid ReDoS
15 if unsafe_pattern_match:
16 raise UnsafePatternError("Potentially unsafe part of the pattern: %s in %s" % (unsafe_pattern_match.group(0), pattern))
17
18 repetitions = re.findall(r"\.[\*\{\+]", pattern)
19 if len(repetitions) >= 10:
20 raise UnsafePatternError("More than 10 repetitions of %s in %s" % (repetitions[0], pattern))
21
22 return True
23
24
25def match(pattern, *args, **kwargs):
26 cached_pattern = cached_patterns.get(pattern)
27 if cached_pattern:
28 return cached_pattern.match(*args, **kwargs)
29 else:
30 if isSafePattern(pattern):
31 cached_patterns[pattern] = re.compile(pattern)
32 return cached_patterns[pattern].match(*args, **kwargs)