diff options
Diffstat (limited to '')
-rw-r--r-- | build/clang-plugin/ThreadAllows.py | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/build/clang-plugin/ThreadAllows.py b/build/clang-plugin/ThreadAllows.py new file mode 100644 index 0000000000..f3e1ee894c --- /dev/null +++ b/build/clang-plugin/ThreadAllows.py @@ -0,0 +1,82 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. +import json +import os +import posixpath +from os import PathLike + +# `typing.Literal` not available until Python 3.8; +# `typing_extensions` not generally available here +from typing import Iterable, Set + +FIRST_LINE = "// This file was generated by {}. DO NOT EDIT.".format( + # `posixpath` for forward slashes, for presentation purposes + posixpath.relpath(__file__, os.getenv("TOPSRCDIR", "/")) +) + + +def generate_allowed_items( + which: str, # should be: Literal["files", "names"], + paths: Iterable[PathLike], +) -> str: + def remove_trailing_comment(s: str) -> str: + return s[0 : s.find("#")] + + def read_items_from_path(path: PathLike) -> Set[str]: + out = set() + with open(path) as file: + for line in file.readlines(): + line = remove_trailing_comment(line).strip() + if not line: + continue # comment or empty line; discard + out.add(line) + return out + + allowed = set().union(*(read_items_from_path(path) for path in paths)) + # BUG: `json.dumps` may not correctly handle use of the quote character in + # thread names + allowed_list_s = ",\n ".join(json.dumps(elem) for elem in sorted(allowed)) + + return f"""\ +static const char *allow_thread_{which}[] = {{ + {allowed_list_s} +}};""" + + +def generate_allows( + *, allowed_names: Iterable[PathLike], allowed_files: Iterable[PathLike] +) -> str: + """ + This function reads in the specified sets of files -- ordinarily, + ["ThreadAllows.txt"] and ["ThreadFileAllows.txt"] -- and generates the text + of a header file containing two arrays with their contents, for inclusion by + the thread-name checker. + + The checker will reject the creation of any thread via NS_NewNamedThread + unless either: + - the thread's name is a literal string which is found in the set of + allowed thread names; or + - the thread's creation occurs within a file which is found in the set of + unchecked files. + + The latter condition exists mostly for the definition of NS_NewNamedThread, + but there also exist a few cases where the thread name is dynamically + computed (and so can't be checked). + """ + output_string = ( + FIRST_LINE + + "\n\n" + + generate_allowed_items("files", allowed_files) + + "\n\n" + + generate_allowed_items("names", allowed_names) + + "\n" + ) + return output_string + + +# Entry point used by build/clang-plugin/moz.build (q.v.). +def generate_file(output, allowed_names, allowed_files): + output.write( + generate_allows(allowed_names=[allowed_names], allowed_files=[allowed_files]) + ) |