ยปCore Development>Code coverage>Tools/ssl/make_ssl_data.py

Python code coverage for Tools/ssl/make_ssl_data.py

#countcontent
1n/a#! /usr/bin/env python3
2n/a
3n/a"""
4n/aThis script should be called *manually* when we want to upgrade SSLError
5n/a`library` and `reason` mnemnonics to a more recent OpenSSL version.
6n/a
7n/aIt takes two arguments:
8n/a- the path to the OpenSSL source tree (e.g. git checkout)
9n/a- the path to the C file to be generated
10n/a (probably Modules/_ssl_data.h)
11n/a"""
12n/a
13n/aimport datetime
14n/aimport os
15n/aimport re
16n/aimport sys
17n/aimport _ssl
18n/a
19n/a
20n/adef parse_error_codes(h_file, prefix, libcode):
21n/a pat = re.compile(r"#define\W+(%s([\w]+))\W+(\d+)\b" % re.escape(prefix))
22n/a codes = []
23n/a with open(h_file, "r", encoding="latin1") as f:
24n/a for line in f:
25n/a match = pat.search(line)
26n/a if match:
27n/a code, name, num = match.groups()
28n/a num = int(num)
29n/a # e.g. ("SSL_R_BAD_DATA", ("ERR_LIB_SSL", "BAD_DATA", 390))
30n/a codes.append((code, (libcode, name, num)))
31n/a return codes
32n/a
33n/aif __name__ == "__main__":
34n/a openssl_inc = sys.argv[1]
35n/a outfile = sys.argv[2]
36n/a use_stdout = outfile == '-'
37n/a f = sys.stdout if use_stdout else open(outfile, "w")
38n/a error_libraries = {
39n/a # mnemonic -> (library code, error prefix, header file)
40n/a 'PEM': ('ERR_LIB_PEM', 'PEM_R_', 'crypto/pem/pem.h'),
41n/a 'SSL': ('ERR_LIB_SSL', 'SSL_R_', 'ssl/ssl.h'),
42n/a 'X509': ('ERR_LIB_X509', 'X509_R_', 'crypto/x509/x509.h'),
43n/a }
44n/a
45n/a # Read codes from libraries
46n/a new_codes = []
47n/a for libcode, prefix, h_file in sorted(error_libraries.values()):
48n/a new_codes += parse_error_codes(os.path.join(openssl_inc, h_file),
49n/a prefix, libcode)
50n/a new_code_nums = set((libcode, num)
51n/a for (code, (libcode, name, num)) in new_codes)
52n/a
53n/a # Merge with existing codes (in case some old codes disappeared).
54n/a codes = {}
55n/a for errname, (libnum, errnum) in _ssl.err_names_to_codes.items():
56n/a lib = error_libraries[_ssl.lib_codes_to_names[libnum]]
57n/a libcode = lib[0] # e.g. ERR_LIB_PEM
58n/a errcode = lib[1] + errname # e.g. SSL_R_BAD_SSL_SESSION_ID_LENGTH
59n/a # Only keep it if the numeric codes weren't reused
60n/a if (libcode, errnum) not in new_code_nums:
61n/a codes[errcode] = libcode, errname, errnum
62n/a codes.update(dict(new_codes))
63n/a
64n/a def w(l):
65n/a f.write(l + "\n")
66n/a w("/* File generated by Tools/ssl/make_ssl_data.py */")
67n/a w("/* Generated on %s */" % datetime.datetime.now().isoformat())
68n/a w("")
69n/a
70n/a w("static struct py_ssl_library_code library_codes[] = {")
71n/a for mnemo, (libcode, _, _) in sorted(error_libraries.items()):
72n/a w(' {"%s", %s},' % (mnemo, libcode))
73n/a w(' { NULL }')
74n/a w('};')
75n/a w("")
76n/a
77n/a w("static struct py_ssl_error_code error_codes[] = {")
78n/a for errcode, (libcode, name, num) in sorted(codes.items()):
79n/a w(' #ifdef %s' % (errcode))
80n/a w(' {"%s", %s, %s},' % (name, libcode, errcode))
81n/a w(' #else')
82n/a w(' {"%s", %s, %d},' % (name, libcode, num))
83n/a w(' #endif')
84n/a w(' { NULL }')
85n/a w('};')
86n/a if not use_stdout:
87n/a f.close()