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