Forking what is left of ZeroNet and hopefully adding an AT Proto Frontend/Proxy
at main 32 lines 1.1 kB view raw
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)