[Tizen] Implement detecting of sanitized libraries
[platform/upstream/coreclr.git] / src / scripts / check-definitions.py
1 #!/usr/bin/env python
2 # Licensed to the .NET Foundation under one or more agreements.
3 # The .NET Foundation licenses this file to you under the MIT license.
4 # See the LICENSE file in the project root for more information.
5 #
6 # check-definitions.py
7 #  This script checks the consistency between compiler definitions
8 # of the native part of CoreCLR and managed part (mscorlib.dll) of
9 # CoreCLR
10 #
11 # Usage:
12 #   $ ./check-definitions.py Definition_File String_of_Definitions [String_of_Ignored_Definitions]
13 #
14 #      Definition_File: the filename of a file containing the list of
15 #          compiler definitions of CMAKE, seperated by line.
16 #          (Mandatory)
17 #      String_of_Definitions: the list of managed code compiler
18 #          definitions, seperated by semicolon without spaces.
19 #          (Mandatory)
20 #      String_of_Ignored_Definitions: the list of compiler definitions
21 #          to be suppressed from emitting warnings, seperated by semicolon without spaces.
22 #          (Optional)
23 #
24 # (c) 2016 MyungJoo Ham <myungjoo.ham@samsung.com>
25
26 from __future__ import print_function
27
28 import sys
29 import re
30 import os
31
32 debug = 0
33
34 # For the native part, return the sorted definition array.
35 def loadDefinitionFile(filename):
36     result = []
37
38     try:
39         with open(filename, 'r') as f:
40             for line in f:
41                 line = line.strip()
42                 if line:
43                     result.append(line)
44     except IOError:
45         # If cmake was not used, this script won't work, and that's ok
46         sys.exit(0)
47
48     result = sorted(result)
49     return result
50
51
52 # For the managed part, return the sorted definition array.
53 def loadDefinitionString(string):
54     splitted = string.split(';')
55     result = []
56     for line in splitted:
57        theLine = line.strip()
58        if (len(theLine) > 0):
59            result.append(theLine)
60
61     result = sorted(result)
62     return result
63
64
65 def getDiff(arrNative, arrManaged):
66     result = [[], []]
67     iF = 0 # From file (native)
68     nF = len(arrNative)
69
70     iS = 0 # From string (managed)
71     nS = len(arrManaged)
72
73     while (iS < nS) and (iF < nF):
74         if (arrNative[iF] == arrManaged[iS]):
75             if (debug == 1):
76                 print("Both have " + arrNative[iF])
77             iF = iF + 1
78             iS = iS + 1
79         elif (arrNative[iF] == (arrManaged[iS] + "=1")):
80             if (debug == 1):
81                 print("Both have " + arrNative[iF] + "(=1)")
82             iF = iF + 1
83             iS = iS + 1
84         elif (arrNative[iF] < arrManaged[iS]):
85             if (debug == 1):
86                 print("--- Managed Omitted " + arrNative[iF])
87             result[1].append(arrNative[iF])
88             iF = iF + 1
89         elif (arrNative[iF] > arrManaged[iS]):
90             if (debug == 1):
91                 print("+++ Managed Added " + arrManaged[iS])
92             result[0].append(arrManaged[iS])
93             iS = iS + 1
94
95     if (iS < nS):
96         while iS < nS:
97             if (debug == 1):
98                 print("+++ Managed Added " + arrManaged[iS])
99             result[0].append(arrManaged[iS])
100             iS = iS + 1
101     elif (iF < nF):
102         while iF < nF:
103             if (debug == 1):
104                 print("--- Managed Omitted " + arrNative[iF])
105             result[1].append(arrNative[iF])
106             iF = iF + 1
107     return result
108
109
110 def printPotentiallyCritical(arrDefinitions, referencedFilename, arrIgnore):
111     content = None
112     with open(referencedFilename, 'r') as f:
113         content = f.read()
114
115     for keyword in arrDefinitions:
116         skip = 0
117
118         if (keyword[-2:] == "=1"):
119             key = keyword[:-2]
120         else:
121             key = keyword
122
123         if re.search("[^\\w]"+key+"[^\\w]", content):
124             for ign in arrIgnore:
125                 if key == ign:
126                     skip = 1
127                     break
128             if skip == 0:
129                 print(keyword)
130
131 # MAIN SCRIPT
132 if len(sys.argv) < 3:
133     print("\nUsage:")
134     print("$ check-definitions.py [ProjectDir] [Definition file] [String of definitions]")
135     print("    Definition file contains the list of cmake (native) compiler definitions")
136     print("      seperated by line.")
137     print("    String of definitions contains the list of csproj (managed) definitions")
138     print("      seperated by semicolons.")
139     sys.exit(-1)
140
141 projectDir = sys.argv[1]
142 filename = sys.argv[2]
143 string = sys.argv[3]
144
145 arrayNative = loadDefinitionFile(filename)
146 arrayManaged = loadDefinitionString(string)
147 arrayIgnore = []
148
149 if len(sys.argv) > 4:
150     arrayIgnore = loadDefinitionString(sys.argv[4])
151
152 arrays = getDiff(arrayNative, arrayManaged)
153 # arrays[0] = array of added in managed
154 # arrays[1] = array of omitted in managed (added in native)
155
156 print("Potentially Dangerous Compiler Definitions in clrdefinitions.cmake (omitted in native build):")
157 printPotentiallyCritical(arrays[0], os.path.join(projectDir, "clrdefinitions.cmake"), arrayIgnore)
158
159 print("Potentially Dangerous Compiler Definitions in clr.featuredefines.props (omitted in managed build):")
160 printPotentiallyCritical(arrays[1], os.path.join(projectDir, "clr.featuredefines.props"), arrayIgnore)
161
162 print("Definition Check Completed.")
163