# HG changeset patch # User hseigel # Date 1444843847 14400 # Node ID edc4431940b2854bd0faf40154e2a9358ec2c672 # Parent da8c3575c0767e46fbd7c70b84cb654c8fdb7696 8139069: JVM should throw ClassFormatError for methods in interfaces Summary: If method being parsed is in an interface, throw ClassFormatError if its name is "" Reviewed-by: acorn, lfoltan diff -r da8c3575c076 -r edc4431940b2 hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Tue Oct 13 17:34:28 2015 +0200 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Oct 14 13:30:47 2015 -0400 @@ -1997,6 +1997,10 @@ verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle)); } + if (name == vmSymbols::object_initializer_name() && is_interface) { + classfile_parse_error("Interface cannot have a method named , class file %s", CHECK_(nullHandle)); + } + int args_size = -1; // only used when _need_verify is true if (_need_verify) { args_size = ((flags & JVM_ACC_STATIC) ? 0 : 1) + diff -r da8c3575c076 -r edc4431940b2 hotspot/src/share/vm/classfile/verifier.cpp --- a/hotspot/src/share/vm/classfile/verifier.cpp Tue Oct 13 17:34:28 2015 +0200 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Oct 14 13:30:47 2015 -0400 @@ -1579,11 +1579,9 @@ return; } // Make sure "this" has been initialized if current method is an - // . Note that "" methods in interfaces are just - // normal methods. Interfaces cannot have ctors. + // . if (_method->name() == vmSymbols::object_initializer_name() && - current_frame.flag_this_uninit() && - !current_class()->is_interface()) { + current_frame.flag_this_uninit()) { verify_error(ErrorContext::bad_code(bci), "Constructor must call super() or this() " "before return"); diff -r da8c3575c076 -r edc4431940b2 hotspot/test/runtime/classFileParserBug/InitInInterface.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/classFileParserBug/InitInInterface.java Wed Oct 14 13:30:47 2015 -0400 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, 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 8139069 + * @summary Check that any method named in an interface causes ClassFormatError + * @compile nonvoidinit.jasm voidinit.jasm + * @run main InitInInterface + */ + +// Test that an method is not allowed in interfaces. +public class InitInInterface { + public static void main(String args[]) throws Throwable { + + System.out.println("Regression test for bug 8130183"); + try { + Class newClass = Class.forName("nonvoidinit"); + throw new RuntimeException( + "ClassFormatError not thrown for non-void in an interface"); + } catch (java.lang.ClassFormatError e) { + if (!e.getMessage().contains("Interface cannot have a method named ")) { + throw new RuntimeException("Unexpected exception nonvoidint: " + e.getMessage()); + } + } + try { + Class newClass = Class.forName("voidinit"); + throw new RuntimeException( + "ClassFormatError not thrown for void in an interface"); + } catch (java.lang.ClassFormatError e) { + if (!e.getMessage().contains("Interface cannot have a method named ")) { + throw new RuntimeException("Unexpected exception voidint: " + e.getMessage()); + } + } + } +} diff -r da8c3575c076 -r edc4431940b2 hotspot/test/runtime/classFileParserBug/nonvoidinit.jasm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/classFileParserBug/nonvoidinit.jasm Wed Oct 14 13:30:47 2015 -0400 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015, 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. + * + */ + +// Interface containing non-void method. +public interface nonvoidinit version 50:0 +{ + + public abstract Method "":"()I"; + +} // end Class nonvoidinit diff -r da8c3575c076 -r edc4431940b2 hotspot/test/runtime/classFileParserBug/voidinit.jasm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/classFileParserBug/voidinit.jasm Wed Oct 14 13:30:47 2015 -0400 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015, 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. + * + */ + +// Interface containing void method. +public interface voidinit version 50:0 +{ + + public abstract Method "":"()V"; + +} // end Class voidinit