Skip to content

Commit a60f45c

Browse files
Merge pull request #5073 from romainbrenguier/bugfix/map-base-at
[TG-9299] Fix crash in case of user provided clinit for a clinit which is not in the symbol table
2 parents 5b3c82d + 1b3c289 commit a60f45c

File tree

3 files changed

+63
-35
lines changed

3 files changed

+63
-35
lines changed

jbmc/src/java_bytecode/assignments_from_json.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,9 @@ void assign_from_json(
838838
location.set_function(function_id);
839839
allocate_objectst allocate(ID_java, location, function_id, symbol_table);
840840
code_blockt body_rec;
841-
const auto class_name = declaring_class(symbol_table.lookup_ref(function_id));
841+
const symbolt *function_symbol = symbol_table.lookup(function_id);
842+
INVARIANT(function_symbol, "Function must appear in symbol table");
843+
const auto class_name = declaring_class(*function_symbol);
842844
INVARIANT(
843845
class_name,
844846
"Function " + id2string(function_id) + " must be declared by a class.");

jbmc/src/java_bytecode/java_static_initializers.cpp

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -792,50 +792,52 @@ code_blockt get_user_specified_clinit_body(
792792
&class_to_declared_symbols_map)
793793
{
794794
const irep_idt &real_clinit_name = clinit_function_name(class_id);
795+
const auto clinit_func = symbol_table.lookup(real_clinit_name);
796+
if(clinit_func == nullptr)
797+
{
798+
// Case where the real clinit doesn't appear in the symbol table, even
799+
// though their is user specifed one. This may occur when some class
800+
// substitution happened after compilation.
801+
return code_blockt{};
802+
}
795803
const auto class_entry =
796804
static_values_json.find(id2string(strip_java_namespace_prefix(class_id)));
797-
if(class_entry != static_values_json.end())
805+
if(class_entry != static_values_json.end() && class_entry->second.is_object())
798806
{
799-
const auto &class_json_value = class_entry->second;
800-
if(class_json_value.is_object())
807+
const auto &class_json_object = to_json_object(class_entry->second);
808+
std::map<symbol_exprt, jsont> static_field_values;
809+
for(const auto &symbol_pair :
810+
equal_range(class_to_declared_symbols_map, class_id))
801811
{
802-
const auto &class_json_object = to_json_object(class_json_value);
803-
std::map<symbol_exprt, jsont> static_field_values;
804-
for(const auto &class_symbol_pair :
805-
equal_range(class_to_declared_symbols_map, class_id))
812+
const symbolt &symbol = symbol_pair.second;
813+
if(symbol.is_static_lifetime)
806814
{
807-
const symbolt &symbol = class_symbol_pair.second;
808-
if(symbol.is_static_lifetime)
815+
const symbol_exprt &static_field_expr = symbol.symbol_expr();
816+
const auto &static_field_entry =
817+
class_json_object.find(id2string(symbol.base_name));
818+
if(static_field_entry != class_json_object.end())
809819
{
810-
const symbol_exprt &static_field_expr = symbol.symbol_expr();
811-
const auto &static_field_entry =
812-
class_json_object.find(id2string(symbol.base_name));
813-
if(static_field_entry != class_json_object.end())
814-
{
815-
static_field_values.insert(
816-
{static_field_expr, static_field_entry->second});
817-
}
820+
static_field_values.insert(
821+
{static_field_expr, static_field_entry->second});
818822
}
819823
}
820-
code_blockt body;
821-
for(const auto &value_pair : static_field_values)
822-
{
823-
assign_from_json(
824-
value_pair.first,
825-
value_pair.second,
826-
real_clinit_name,
827-
body,
828-
symbol_table,
829-
needed_lazy_methods,
830-
max_user_array_length,
831-
references);
832-
}
833-
return body;
834824
}
825+
code_blockt body;
826+
for(const auto &value_pair : static_field_values)
827+
{
828+
assign_from_json(
829+
value_pair.first,
830+
value_pair.second,
831+
real_clinit_name,
832+
body,
833+
symbol_table,
834+
needed_lazy_methods,
835+
max_user_array_length,
836+
references);
837+
}
838+
return body;
835839
}
836-
if(const auto clinit_func = symbol_table.lookup(real_clinit_name))
837-
return code_blockt{{code_function_callt{clinit_func->symbol_expr()}}};
838-
return code_blockt{};
840+
return code_blockt{{code_function_callt{clinit_func->symbol_expr()}}};
839841
}
840842

841843
/// Create static initializer wrappers and possibly user-specified functions for

jbmc/unit/java_bytecode/java_static_initializers/java_static_initializers.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,30 @@ SCENARIO("get_user_specified_clinit_body", "[core][java_static_initializers]")
108108
REQUIRE(clinit_body == code_blockt{});
109109
}
110110
}
111+
GIVEN(
112+
"A class which has an entry in the JSON object but no clinit defined "
113+
"in the symbol table")
114+
{
115+
static_values_json["TestClass"] = [] {
116+
json_objectt entry{};
117+
entry["field_name"] = json_numbert{"42"};
118+
return entry;
119+
}();
120+
121+
const code_blockt clinit_body = get_user_specified_clinit_body(
122+
"java::TestClass",
123+
static_values_json,
124+
symbol_table,
125+
{},
126+
max_user_array_length,
127+
references,
128+
class_to_declared_symbols);
129+
130+
THEN("User provided clinit body is empty")
131+
{
132+
REQUIRE(clinit_body == code_blockt{});
133+
}
134+
}
111135
GIVEN("A class which has a static number in the provided JSON")
112136
{
113137
static_values_json["TestClass"] = [] {

0 commit comments

Comments
 (0)