@@ -10,7 +10,9 @@ class Expr:
10
10
11
11
def __init__ (self , expr ):
12
12
if expr ['namedSub' ]['type' ]['id' ] == 'symbol' :
13
- self .type_identifier = expr ['namedSub' ]['type' ]['namedSub' ]['identifier' ]['id' ]
13
+ self .type_identifier = expr ['namedSub' ]['type' ]['namedSub' ]['identifier' ]['id' ].replace ('java::' , '' )
14
+ elif expr ['namedSub' ]['type' ]['id' ] == 'struct' :
15
+ self .type_identifier = expr ['namedSub' ]['type' ]['namedSub' ]['base_name' ]['id' ]
14
16
else :
15
17
self .type_identifier = None
16
18
@@ -27,6 +29,28 @@ def __init__(self, dynamic_object_expr):
27
29
dynamic_object_expr ['namedSub' ]['is_most_recent_allocation' ]['id' ] == 'most_recent_allocation'
28
30
29
31
32
+ class TypecastDynamicObject (Expr ):
33
+ """Turn the json for a typecast dynamic object expr into a python object"""
34
+
35
+ def __init__ (self , typecast_dynamic_object_expr ):
36
+ assert typecast_dynamic_object_expr ['id' ] == 'typecast'
37
+ assert typecast_dynamic_object_expr ['sub' ][0 ]['id' ] == 'dynamic_object'
38
+ Expr .__init__ (self , typecast_dynamic_object_expr )
39
+ self .dynamic_object = DynamicObject (typecast_dynamic_object_expr ['sub' ][0 ])
40
+
41
+
42
+ class SoftCastDynamicObject (Expr ):
43
+ """Turn the json for a soft-cast dynamic object expr into a python object"""
44
+
45
+ def __init__ (self , soft_cast_dynamic_object_expr ):
46
+ assert soft_cast_dynamic_object_expr ['id' ] == 'member'
47
+ assert soft_cast_dynamic_object_expr ['namedSub' ]['component_name' ]['id' ].startswith ('@' )
48
+ assert soft_cast_dynamic_object_expr ['sub' ][0 ]['id' ] == 'dynamic_object'
49
+ Expr .__init__ (self , soft_cast_dynamic_object_expr )
50
+ assert soft_cast_dynamic_object_expr ['namedSub' ]['component_name' ]['id' ] == '@' + self .type_identifier
51
+ self .dynamic_object = DynamicObject (soft_cast_dynamic_object_expr ['sub' ][0 ])
52
+
53
+
30
54
class EvsType (Enum ):
31
55
root_object = '0'
32
56
per_field = '1'
@@ -72,13 +96,19 @@ def __init__(self, evs_expr):
72
96
else :
73
97
assert False
74
98
99
+
75
100
class ValueSetExpectation :
76
101
"""Encapsulate the states that a particular variable can take"""
77
102
78
103
def __init__ (self , var_state ):
79
104
self .var_state = var_state ['values' ]
80
105
self .null_objects = [x for x in self .var_state if x ['id' ] == 'NULL-object' ]
81
106
self .dynamic_objects = [DynamicObject (x ) for x in self .var_state if x ['id' ] == 'dynamic_object' ]
107
+ self .typecast_dynamic_objects = [TypecastDynamicObject (x ) for x in self .var_state if x ['id' ] ==
108
+ 'typecast' and x ['sub' ][0 ]['id' ] == 'dynamic_object' ]
109
+ self .soft_cast_dynamic_objects = [SoftCastDynamicObject (x ) for x in self .var_state if
110
+ x ['id' ] == 'member' and x ['namedSub' ]['component_name' ]['id' ].startswith (
111
+ '@' ) and x ['sub' ][0 ]['id' ] == 'dynamic_object' ]
82
112
self .external_value_sets = [ExternalValueSet (x ) for x in self .var_state if x ['id' ] == 'external_value_set' ]
83
113
self .unknown = [x for x in self .var_state if x ['id' ] == 'unknown' ]
84
114
@@ -100,6 +130,23 @@ def check_contains_dynamic_object(self, expected_number=1, is_most_recent_alloca
100
130
matches = [x for x in matches if x .is_most_recent_allocation == is_most_recent_allocation ]
101
131
assert expected_number == len (matches )
102
132
133
+ def check_contains_typecast_dynamic_object (self , expected_number = 1 , is_most_recent_allocation = None , type = None ):
134
+ matches = self .typecast_dynamic_objects
135
+ if is_most_recent_allocation is not None :
136
+ # Expect True or False
137
+ matches = [x for x in matches if x .dynamic_object .is_most_recent_allocation == is_most_recent_allocation ]
138
+ if type is not None :
139
+ # Expect string
140
+ matches = [x for x in matches if x .type_identifier == type ]
141
+ assert expected_number == len (matches )
142
+
143
+ def check_contains_soft_cast_dynamic_object (self , expected_number = 1 , is_most_recent_allocation = None , type = None ):
144
+ matches = self .soft_cast_dynamic_objects
145
+ if is_most_recent_allocation is not None :
146
+ # Expect string
147
+ matches = [x for x in matches if x .type_identifier == type ]
148
+ assert expected_number == len (matches )
149
+
103
150
def check_contains_root_object_evs (self , expected_number = 1 , label_suffix = None ):
104
151
matches = [x for x in self .external_value_sets if x .evs_type == EvsType .root_object ]
105
152
if label_suffix is not None :
@@ -267,7 +314,8 @@ def run(self):
267
314
class_path = os .path .join ('LVSA' , self .folder_name , self .class_filename )
268
315
cmd = [executable_path , '--local-value-set-analysis' , '--lvsa-summary-directory' , self .temp_dir_path ,
269
316
'--function' , fq_function_name , '--show-value-sets' , '--json-ui' ]
270
- if "SECURITY_REGRESSION_TESTS_USE_CSVSA" in os .environ and os .environ ["SECURITY_REGRESSION_TESTS_USE_CSVSA" ] != 0 :
317
+ if "SECURITY_REGRESSION_TESTS_USE_CSVSA" in os .environ and os .environ [
318
+ "SECURITY_REGRESSION_TESTS_USE_CSVSA" ] != 0 :
271
319
cmd .append ("--lazy-methods-context-sensitive" )
272
320
if self .max_input_tree_depth is not None :
273
321
cmd += ['--java-max-input-tree-depth' , str (self .max_input_tree_depth )]
0 commit comments