mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-14 01:43:13 +00:00
8376521: Verifier: disallow acmp & ifnull on 'uninitialized' types
8375483: Should set flagThisUninit whenever uninitializedThis is on the stack Reviewed-by: liach, coleenp
This commit is contained in:
parent
bf28e03eeb
commit
e760171da8
@ -1607,12 +1607,12 @@ void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
|
||||
case Bytecodes::_if_acmpeq :
|
||||
case Bytecodes::_if_acmpne :
|
||||
current_frame.pop_stack(
|
||||
VerificationType::reference_check(), CHECK_VERIFY(this));
|
||||
object_type(), CHECK_VERIFY(this));
|
||||
// fall through
|
||||
case Bytecodes::_ifnull :
|
||||
case Bytecodes::_ifnonnull :
|
||||
current_frame.pop_stack(
|
||||
VerificationType::reference_check(), CHECK_VERIFY(this));
|
||||
object_type(), CHECK_VERIFY(this));
|
||||
stackmap_table.check_jump_target
|
||||
(¤t_frame, bcs.bci(), bcs.get_offset_s2(), CHECK_VERIFY(this));
|
||||
no_control_flow = false; break;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1047,13 +1047,11 @@ public final class VerifierImpl {
|
||||
no_control_flow = false; break;
|
||||
case IF_ACMPEQ :
|
||||
case IF_ACMPNE :
|
||||
current_frame.pop_stack(
|
||||
VerificationType.reference_check);
|
||||
current_frame.pop_stack(object_type());
|
||||
// fall through
|
||||
case IFNULL :
|
||||
case IFNONNULL :
|
||||
current_frame.pop_stack(
|
||||
VerificationType.reference_check);
|
||||
current_frame.pop_stack(object_type());
|
||||
target = bcs.dest();
|
||||
stackmap_table.check_jump_target
|
||||
(current_frame, target);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -2162,8 +2162,7 @@ pop_stack(context_type *context, unsigned int inumber, stack_info_type *new_stac
|
||||
break;
|
||||
if ( (GET_ITEM_TYPE(top_type) == ITEM_NewObject
|
||||
|| (GET_ITEM_TYPE(top_type) == ITEM_InitObject))
|
||||
&& ((opcode == JVM_OPC_astore) || (opcode == JVM_OPC_aload)
|
||||
|| (opcode == JVM_OPC_ifnull) || (opcode == JVM_OPC_ifnonnull)))
|
||||
&& ((opcode == JVM_OPC_astore) || (opcode == JVM_OPC_aload)))
|
||||
break;
|
||||
/* The 2nd edition VM of the specification allows field
|
||||
* initializations before the superclass initializer,
|
||||
|
||||
43
test/hotspot/jtreg/runtime/verifier/UninitThisAcmp.jasm
Normal file
43
test/hotspot/jtreg/runtime/verifier/UninitThisAcmp.jasm
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
class UninitThisAcmp version 69:0
|
||||
{
|
||||
public Method "<init>":"()V"
|
||||
stack 2 locals 2
|
||||
{
|
||||
new class java/lang/Object;
|
||||
dup;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
astore_1;
|
||||
aload_0;
|
||||
aload_1;
|
||||
if_acmpne L14;
|
||||
nop;
|
||||
L14: stack_frame_type append;
|
||||
locals_map class java/lang/Object;
|
||||
aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
} // end Class UninitThisAcmp
|
||||
41
test/hotspot/jtreg/runtime/verifier/UninitThisAcmpOld.jasm
Normal file
41
test/hotspot/jtreg/runtime/verifier/UninitThisAcmpOld.jasm
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
class UninitThisAcmpOld version 49:0
|
||||
{
|
||||
public Method "<init>":"()V"
|
||||
stack 2 locals 2
|
||||
{
|
||||
new class java/lang/Object;
|
||||
dup;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
astore_1;
|
||||
aload_0;
|
||||
aload_1;
|
||||
if_acmpne L14;
|
||||
nop;
|
||||
L14: aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
} // end Class UninitThisAcmpOld
|
||||
42
test/hotspot/jtreg/runtime/verifier/UninitThisIfNull.jasm
Normal file
42
test/hotspot/jtreg/runtime/verifier/UninitThisIfNull.jasm
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
class UninitThisIfNull version 69:0
|
||||
{
|
||||
public Method "<init>":"()V"
|
||||
stack 2 locals 2
|
||||
{
|
||||
new class java/lang/Object;
|
||||
dup;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
astore_1;
|
||||
aload_0;
|
||||
ifnonnull L14;
|
||||
nop;
|
||||
L14: stack_frame_type append;
|
||||
locals_map class java/lang/Object;
|
||||
aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
} // end Class UninitThisIfNull
|
||||
40
test/hotspot/jtreg/runtime/verifier/UninitThisIfNullOld.jasm
Normal file
40
test/hotspot/jtreg/runtime/verifier/UninitThisIfNullOld.jasm
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
class UninitThisIfNullOld version 49:0
|
||||
{
|
||||
public Method "<init>":"()V"
|
||||
stack 2 locals 2
|
||||
{
|
||||
new class java/lang/Object;
|
||||
dup;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
astore_1;
|
||||
aload_0;
|
||||
ifnonnull L14;
|
||||
nop;
|
||||
L14: aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
} // end Class UninitThisIfNullOld
|
||||
44
test/hotspot/jtreg/runtime/verifier/UninitializedAcmp.jasm
Normal file
44
test/hotspot/jtreg/runtime/verifier/UninitializedAcmp.jasm
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
class UninitializedAcmp version 69:0
|
||||
{
|
||||
Method "<init>":"()V"
|
||||
stack 5 locals 1
|
||||
{
|
||||
aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
aload_0;
|
||||
L1: new class java/lang/Object;
|
||||
dup;
|
||||
dup;
|
||||
dup;
|
||||
if_acmpne L18;
|
||||
nop;
|
||||
L18: stack_frame_type full;
|
||||
locals_map class UninitializedAcmp;
|
||||
stack_map class UninitializedAcmp, at L1, at L1;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
} // end Class UninitializedAcmp
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
class UninitializedAcmpOld version 49:0
|
||||
{
|
||||
Method "<init>":"()V"
|
||||
stack 5 locals 1
|
||||
{
|
||||
aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
aload_0;
|
||||
L1: new class java/lang/Object;
|
||||
dup;
|
||||
dup;
|
||||
dup;
|
||||
if_acmpne L18;
|
||||
nop;
|
||||
L18: invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
} // end Class UninitializedAcmpOld
|
||||
42
test/hotspot/jtreg/runtime/verifier/UninitializedIfNull.jasm
Normal file
42
test/hotspot/jtreg/runtime/verifier/UninitializedIfNull.jasm
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
class UninitializedIfNull version 69:0
|
||||
{
|
||||
Method "<init>":"()V"
|
||||
stack 3 locals 1
|
||||
{
|
||||
aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
L1: new class java/lang/Object;
|
||||
dup;
|
||||
dup;
|
||||
ifnonnull L18;
|
||||
nop;
|
||||
L18: stack_frame_type full;
|
||||
locals_map class UninitializedIfNull;
|
||||
stack_map at L1, at L1;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
} // end Class UninitializedIfNull
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
class UninitializedIfNullOld version 49:0
|
||||
{
|
||||
Method "<init>":"()V"
|
||||
stack 3 locals 1
|
||||
{
|
||||
aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
L1: new class java/lang/Object;
|
||||
dup;
|
||||
dup;
|
||||
ifnonnull L18;
|
||||
nop;
|
||||
L18: invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
} // end Class UninitializedIfNullOld
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8366743
|
||||
* @summary Test spec rules for uninitialized
|
||||
* @compile UninitThisAcmp.jasm UninitThisIfNull.jasm
|
||||
* UninitializedIfNull.jasm UninitializedAcmp.jasm
|
||||
* UninitThisAcmpOld.jasm UninitThisIfNullOld.jasm
|
||||
* UninitializedAcmpOld.jasm UninitializedIfNullOld.jasm
|
||||
* @run main/othervm -Xlog:verification UninitializedThisVerificationTest
|
||||
*/
|
||||
|
||||
public class UninitializedThisVerificationTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String[] testNames = { "UninitThisAcmp", "UninitThisIfNull",
|
||||
"UninitializedAcmp", "UninitializedIfNull",
|
||||
"UninitThisAcmpOld", "UninitThisIfNullOld",
|
||||
"UninitializedAcmpOld", "UninitializedIfNullOld" };
|
||||
int fails = 0;
|
||||
for (String test : testNames) {
|
||||
System.out.println("Testing " + test);
|
||||
try {
|
||||
Class c = Class.forName(test);
|
||||
System.out.println("Failed");
|
||||
fails++;
|
||||
} catch (java.lang.VerifyError e) {
|
||||
System.out.println("Passed");
|
||||
}
|
||||
}
|
||||
|
||||
if (fails > 0) {
|
||||
throw new RuntimeException("Failed: Expected VerifyError in " + fails + " tests");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -37,12 +37,14 @@ import static java.lang.constant.ConstantDescs.*;
|
||||
|
||||
import java.lang.constant.MethodTypeDesc;
|
||||
import java.lang.invoke.MethodHandleInfo;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -59,6 +61,9 @@ import jdk.internal.classfile.impl.BufWriterImpl;
|
||||
import jdk.internal.classfile.impl.DirectClassBuilder;
|
||||
import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ -418,6 +423,71 @@ class VerifierSelfTest {
|
||||
return lst;
|
||||
}
|
||||
|
||||
enum ComparisonInstruction {
|
||||
IF_ACMPEQ(Opcode.IF_ACMPEQ, 2),
|
||||
IF_ACMPNE(Opcode.IF_ACMPNE, 2),
|
||||
IFNONNULL(Opcode.IFNONNULL, 1),
|
||||
IFNULL(Opcode.IFNULL, 1);
|
||||
final Opcode opcode;
|
||||
final int argCount;
|
||||
ComparisonInstruction(Opcode opcode, int argCount) {
|
||||
this.opcode = opcode;
|
||||
this.argCount = argCount;
|
||||
}
|
||||
}
|
||||
|
||||
enum UninitializeKind {
|
||||
UNINITIALIZED, UNINITIALIZED_THIS
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("uninitializedInBytecodeClasses")
|
||||
public void testUninitializedInComparisons(ComparisonInstruction inst, UninitializeKind kind) throws Throwable {
|
||||
var bytes = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS).build(ClassDesc.of("Test"), clb -> clb
|
||||
.withMethodBody(INIT_NAME, MTD_void, 0, cob -> {
|
||||
StackMapFrameInfo.VerificationTypeInfo uninitializeInfo;
|
||||
if (kind == UninitializeKind.UNINITIALIZED) {
|
||||
uninitializeInfo = StackMapFrameInfo.UninitializedVerificationTypeInfo.of(cob.newBoundLabel());
|
||||
cob.new_(CD_Object);
|
||||
} else {
|
||||
uninitializeInfo = StackMapFrameInfo.SimpleVerificationTypeInfo.UNINITIALIZED_THIS;
|
||||
cob.aload(0);
|
||||
}
|
||||
|
||||
// Stack: uninitializeInfo
|
||||
for (int i = 0; i < inst.argCount; i++) {
|
||||
cob.dup();
|
||||
}
|
||||
var dest = cob.newLabel();
|
||||
cob.branch(inst.opcode, dest)
|
||||
.nop()
|
||||
.labelBinding(dest)
|
||||
.with(StackMapTableAttribute.of(List.of(StackMapFrameInfo.of(dest,
|
||||
List.of(StackMapFrameInfo.SimpleVerificationTypeInfo.UNINITIALIZED_THIS),
|
||||
List.of(uninitializeInfo)))))
|
||||
.invokespecial(CD_Object, INIT_NAME, MTD_void);
|
||||
if (kind == UninitializeKind.UNINITIALIZED) {
|
||||
// still need to call super constructor
|
||||
cob.aload(0)
|
||||
.invokespecial(CD_Object, INIT_NAME, MTD_void);
|
||||
}
|
||||
cob.return_();
|
||||
}));
|
||||
var errors = ClassFile.of().verify(bytes);
|
||||
assertNotEquals(List.of(), errors, () -> errors + " : " + ClassFile.of().parse(bytes).toDebugString());
|
||||
var lookup = MethodHandles.lookup();
|
||||
assertThrows(VerifyError.class, () -> lookup.defineHiddenClass(bytes, true)); // force JVM verification
|
||||
}
|
||||
|
||||
public static Stream<Arguments> uninitializedInBytecodeClasses() {
|
||||
return Arrays.stream(ComparisonInstruction.values())
|
||||
.mapMulti((inst, sink) -> {
|
||||
for (var kind : UninitializeKind.values()) {
|
||||
sink.accept(Arguments.of(inst, kind));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test // JDK-8350029
|
||||
void testInvokeSpecialInterfacePatch() {
|
||||
var runClass = ClassDesc.of("Run");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user