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