1# -*- coding: utf-8 -*- 2# Copyright 2018 The ChromiumOS Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Allowlist functions.""" 7 8 9import glob 10import os 11import re 12 13 14# Matching a string of length m in an NFA of size n is O(mn^2), but the 15# performance also depends largely on the implementation. It appears to be fast 16# enough according to the tests. 17# 18# The performance bottleneck of this script is readelf. Unless this becomes 19# slower than readelf, don't waste time here. 20def is_allowlisted(list_name, pattern): 21 """Check whether the given pattern is specified in the allowlist. 22 23 Args: 24 list_name: name of the allowlist. 25 pattern: the target string. 26 27 Returns: 28 True if matched otherwise False. 29 """ 30 return pattern and allowlists[list_name].match(pattern) 31 32 33def prepare_allowlist(patterns): 34 """Join and compile the re patterns. 35 36 Args: 37 patterns: regex patterns. 38 39 Returns: 40 A compiled re object. 41 """ 42 return re.compile("|".join(patterns)) 43 44 45def load_allowlists(dirname): 46 """Load allowlists under dirname. 47 48 An allowlist ends with .allowlist. 49 50 Args: 51 dirname: path to the dir. 52 53 Returns: 54 A dictionary of 'filename' -> allowlist matcher. 55 """ 56 wlist = {} 57 for fn in glob.glob(os.path.join(dirname, "*.allowlist")): 58 key = os.path.splitext(os.path.basename(fn))[0] 59 with open(fn, "r", encoding="utf-8") as f: 60 patterns = f.read().splitlines() 61 patterns = [l for l in patterns if l != ""] 62 patterns = [l for l in patterns if l[0] != "#"] 63 wlist[key] = prepare_allowlist(patterns) 64 return wlist 65 66 67allowlists = load_allowlists(os.path.dirname(__file__)) 68