Skip to content

Commit e11163c

Browse files
author
Matthias Güdemann
committed
Continue parsing after unsupported BootstrapMethods entry
Before it was possible to keep some `BootstrapMethods` entries unparsed, after a currently unsupported was found. This lead to the situation that JBMC ended up with a wrong file offset which caused problems in the case of class file attributes being present after the `BootstrapMethods` attribute. This was not observed using the Oracle or OpenJDK compilers, but currently only on the Eclipse compiler for Java.
1 parent 06ab440 commit e11163c

File tree

1 file changed

+65
-56
lines changed

1 file changed

+65
-56
lines changed

src/java_bytecode/java_bytecode_parser.cpp

+65-56
Original file line numberDiff line numberDiff line change
@@ -1803,7 +1803,7 @@ java_bytecode_parsert::parse_method_handle(const method_handle_infot &entry)
18031803
void java_bytecode_parsert::read_bootstrapmethods_entry(classt &parsed_class)
18041804
{
18051805
u2 num_bootstrap_methods = read_u2();
1806-
for(size_t i = 0; i < num_bootstrap_methods; i++)
1806+
for(size_t j = 0; j < num_bootstrap_methods; j++)
18071807
{
18081808
u2 bootstrap_methodhandle_ref = read_u2();
18091809
const pool_entryt &entry = pool_entry(bootstrap_methodhandle_ref);
@@ -1868,72 +1868,81 @@ void java_bytecode_parsert::read_bootstrapmethods_entry(classt &parsed_class)
18681868
lambda_method_handlet lambda_method_handle;
18691869
lambda_method_handle.handle_type = method_handle_typet::UNKNOWN_HANDLE;
18701870
lambda_method_handle.u2_values = std::move(u2_values);
1871-
parsed_class.lambda_method_handle_map[{parsed_class.name, i}] =
1871+
parsed_class.lambda_method_handle_map[{parsed_class.name, j}] =
18721872
lambda_method_handle;
1873-
return;
1874-
}
1875-
const pool_entryt &interface_type_argument = pool_entry(argument_index1);
1876-
const pool_entryt &method_handle_argument = pool_entry(argument_index2);
1877-
const pool_entryt &method_type_argument = pool_entry(argument_index3);
1878-
1879-
if(
1880-
!(interface_type_argument.tag == CONSTANT_MethodType &&
1881-
method_handle_argument.tag == CONSTANT_MethodHandle &&
1882-
method_type_argument.tag == CONSTANT_MethodType))
1883-
{
1884-
lambda_method_handlet lambda_method_handle;
1885-
lambda_method_handle.handle_type = method_handle_typet::UNKNOWN_HANDLE;
1886-
lambda_method_handle.u2_values = std::move(u2_values);
1887-
parsed_class.lambda_method_handle_map[{parsed_class.name, i}] =
1888-
lambda_method_handle;
1889-
return;
1890-
}
1891-
1892-
debug() << "INFO: parse lambda handle" << eom;
1893-
optionalt<lambda_method_handlet> lambda_method_handle =
1894-
parse_method_handle(method_handle_infot{method_handle_argument});
1895-
1896-
if(!lambda_method_handle.has_value())
1897-
{
1898-
lambda_method_handlet lambda_method_handle;
1899-
lambda_method_handle.handle_type = method_handle_typet::UNKNOWN_HANDLE;
1900-
lambda_method_handle.u2_values = std::move(u2_values);
1901-
parsed_class.lambda_method_handle_map[{parsed_class.name, i}] =
1902-
lambda_method_handle;
1903-
return;
1904-
}
1905-
else if(
1906-
lambda_method_handle->handle_type !=
1907-
method_handle_typet::LAMBDA_METHOD_HANDLE)
1908-
{
1909-
lambda_method_handle->u2_values = std::move(u2_values);
1910-
error() << "ERROR: could not parse lambda function method handle"
1911-
<< eom;
19121873
}
19131874
else
19141875
{
1915-
lambda_method_handle->interface_type =
1916-
pool_entry(interface_type_argument.ref1).s;
1917-
lambda_method_handle->method_type =
1918-
pool_entry(method_type_argument.ref1).s;
1919-
lambda_method_handle->u2_values = std::move(u2_values);
1920-
debug() << "lambda function reference "
1921-
<< id2string(lambda_method_handle->lambda_method_name)
1922-
<< " in class \"" << parsed_class.name << "\""
1923-
<< "\n interface type is "
1924-
<< id2string(pool_entry(interface_type_argument.ref1).s)
1925-
<< "\n method type is "
1926-
<< id2string(pool_entry(method_type_argument.ref1).s) << eom;
1876+
const pool_entryt &interface_type_argument =
1877+
pool_entry(argument_index1);
1878+
const pool_entryt &method_handle_argument = pool_entry(argument_index2);
1879+
const pool_entryt &method_type_argument = pool_entry(argument_index3);
1880+
1881+
if(
1882+
!(interface_type_argument.tag == CONSTANT_MethodType &&
1883+
method_handle_argument.tag == CONSTANT_MethodHandle &&
1884+
method_type_argument.tag == CONSTANT_MethodType))
1885+
{
1886+
lambda_method_handlet lambda_method_handle;
1887+
lambda_method_handle.handle_type =
1888+
method_handle_typet::UNKNOWN_HANDLE;
1889+
lambda_method_handle.u2_values = std::move(u2_values);
1890+
parsed_class.lambda_method_handle_map[{parsed_class.name, j}] =
1891+
lambda_method_handle;
1892+
}
1893+
else
1894+
{
1895+
debug() << "INFO: parse lambda handle" << eom;
1896+
optionalt<lambda_method_handlet> lambda_method_handle =
1897+
parse_method_handle(method_handle_infot{method_handle_argument});
1898+
1899+
if(!lambda_method_handle.has_value())
1900+
{
1901+
lambda_method_handlet lambda_method_handle;
1902+
lambda_method_handle.handle_type =
1903+
method_handle_typet::UNKNOWN_HANDLE;
1904+
lambda_method_handle.u2_values = std::move(u2_values);
1905+
parsed_class.lambda_method_handle_map[{parsed_class.name, j}] =
1906+
lambda_method_handle;
1907+
}
1908+
else
1909+
{
1910+
if(
1911+
lambda_method_handle->handle_type !=
1912+
method_handle_typet::LAMBDA_METHOD_HANDLE)
1913+
{
1914+
lambda_method_handle->u2_values = std::move(u2_values);
1915+
error() << "ERROR: could not parse lambda function method handle"
1916+
<< eom;
1917+
}
1918+
else
1919+
{
1920+
lambda_method_handle->interface_type =
1921+
pool_entry(interface_type_argument.ref1).s;
1922+
lambda_method_handle->method_type =
1923+
pool_entry(method_type_argument.ref1).s;
1924+
lambda_method_handle->u2_values = std::move(u2_values);
1925+
debug() << "lambda function reference "
1926+
<< id2string(lambda_method_handle->lambda_method_name)
1927+
<< " in class \"" << parsed_class.name << "\""
1928+
<< "\n interface type is "
1929+
<< id2string(pool_entry(interface_type_argument.ref1).s)
1930+
<< "\n method type is "
1931+
<< id2string(pool_entry(method_type_argument.ref1).s)
1932+
<< eom;
1933+
}
1934+
parsed_class.lambda_method_handle_map[{parsed_class.name, j}] =
1935+
*lambda_method_handle;
1936+
}
1937+
}
19271938
}
1928-
parsed_class.lambda_method_handle_map[{parsed_class.name, i}] =
1929-
*lambda_method_handle;
19301939
}
19311940
else
19321941
{
19331942
lambda_method_handlet lambda_method_handle;
19341943
lambda_method_handle.handle_type = method_handle_typet::UNKNOWN_HANDLE;
19351944
lambda_method_handle.u2_values = std::move(u2_values);
1936-
parsed_class.lambda_method_handle_map[{parsed_class.name, i}] =
1945+
parsed_class.lambda_method_handle_map[{parsed_class.name, j}] =
19371946
lambda_method_handle;
19381947
error() << "ERROR: num_bootstrap_arguments must be at least 3" << eom;
19391948
}

0 commit comments

Comments
 (0)