Commit 9933fac0 authored by Eric Bruneton's avatar Eric Bruneton

Add more tests again, and fix a refactoring bug found with them.

parent f620ada7
Pipeline #470 passed with stage
in 10 minutes and 25 seconds
......@@ -172,21 +172,41 @@ public abstract class AsmTest {
/** @return the content of this class. */
public byte[] getBytes() {
String resourceName = name.replace('.', '/') + ".class";
try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(resourceName)) {
assertNotNull(inputStream, "Class not found " + name);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] data = new byte[inputStream.available()];
int bytesRead;
while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
outputStream.write(data, 0, bytesRead);
}
outputStream.flush();
return outputStream.toByteArray();
} catch (IOException e) {
fail("Can't read " + name);
return new byte[0];
}
return AsmTest.getBytes(name);
}
@Override
public String toString() {
return name;
}
}
/**
* An invalid class, hand-crafted to contain some set of invalid class file structures. These
* classes are not compiled as part of the build. Instead, they have been compiled beforehand, and
* then manually edited to introduce errors.
*/
public enum InvalidClass {
INVALID_BYTECODE_OFFSET("invalid.InvalidBytecodeOffset"),
INVALID_CLASS_VERSION("invalid.InvalidClassVersion"),
INVALID_CONSTANT_POOL_INDEX("invalid.InvalidConstantPoolIndex"),
INVALID_CP_INFO_TAG("invalid.InvalidCpInfoTag"),
INVALID_ELEMENT_VALUE("invalid.InvalidElementValue"),
INVALID_INSN_TYPE_ANNOTATION_TARGET_TYPE("invalid.InvalidInsnTypeAnnotationTargetType"),
INVALID_OPCODE("invalid.InvalidOpcode"),
INVALID_STACK_MAP_FRAME_TYPE("invalid.InvalidStackMapFrameType"),
INVALID_TYPE_ANNOTATION_TARGET_TYPE("invalid.InvalidTypeAnnotationTargetType"),
INVALID_VERIFICATION_TYPE_INFO("invalid.InvalidVerificationTypeInfo");
private final String name;
private InvalidClass(String name) {
this.name = name;
}
/** @return the content of this class. */
public byte[] getBytes() {
return AsmTest.getBytes(name);
}
@Override
......@@ -288,7 +308,7 @@ public abstract class AsmTest {
try {
String dump = new ClassDump(classFile).toString();
assertTrue(dump.contains(expectedString));
} catch (IOException e) {
} catch (IOException | IllegalArgumentException e) {
fail("Class can't be dumped");
}
}
......@@ -305,7 +325,7 @@ public abstract class AsmTest {
String dump = new ClassDump(classFile).toString();
String expectedDump = new ClassDump(expectedClassFile).toString();
assertEquals(expectedDump, dump);
} catch (IOException e) {
} catch (IOException | IllegalArgumentException e) {
fail("Class can't be dumped");
}
}
......@@ -391,4 +411,22 @@ public abstract class AsmTest {
}
}
}
private static byte[] getBytes(String name) {
String resourceName = name.replace('.', '/') + ".class";
try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(resourceName)) {
assertNotNull(inputStream, "Class not found " + name);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] data = new byte[inputStream.available()];
int bytesRead;
while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
outputStream.write(data, 0, bytesRead);
}
outputStream.flush();
return outputStream.toByteArray();
} catch (IOException e) {
fail("Can't read " + name);
return new byte[0];
}
}
}
......@@ -149,7 +149,11 @@ class ClassDump {
private static void dumpClassFile(Parser parser, Builder builder) throws IOException {
builder.add("magic: ", parser.u4());
builder.add("minor_version: ", parser.u2());
builder.add("major_version: ", parser.u2());
int majorVersion = parser.u2();
if (majorVersion >= /* V10 = */ 54) {
throw new IOException("Unsupported class version");
}
builder.add("major_version: ", majorVersion);
int constantPoolCount = parser.u2();
int cpIndex = 1;
while (cpIndex < constantPoolCount) {
......@@ -1390,7 +1394,7 @@ class ClassDump {
for (int j = 0; j < frameType - 251; ++j) {
dumpVerificationTypeInfo(parser, builder);
}
} else if (frameType == 255) {
} else {
int offsetDelta = parser.u2();
bytecodeOffset += offsetDelta + 1;
builder.addInsnIndex("FULL ", bytecodeOffset);
......@@ -1402,8 +1406,6 @@ class ClassDump {
for (int j = 0; j < numberOfStackItems; ++j) {
dumpVerificationTypeInfo(parser, builder);
}
} else {
throw new IOException("Unknown frame_type: " + frameType);
}
}
}
......@@ -2126,9 +2128,11 @@ class ClassDump {
@Override
public <C extends CpInfo> C getCpInfo(int cpIndex, Class<C> cpInfoType) {
Object cpInfo = get(CP_INFO_KEY | cpIndex);
if (cpInfo != null && !cpInfoType.isInstance(cpInfo)) {
if (cpInfo == null) {
throw new IllegalArgumentException("Invalid constant pool index: " + cpIndex);
} else if (!cpInfoType.isInstance(cpInfo)) {
throw new IllegalArgumentException(
"Invalid constant pool type :"
"Invalid constant pool type: "
+ cpInfo.getClass().getName()
+ " should be "
+ cpInfoType.getName());
......@@ -2140,7 +2144,7 @@ class ClassDump {
public int getInsnIndex(int bytecodeOffset) {
Integer insnIndex = (Integer) get(bytecodeOffset);
if (insnIndex == null) {
throw new IllegalArgumentException("Invalid bytecode offset:" + bytecodeOffset);
throw new IllegalArgumentException("Invalid bytecode offset: " + bytecodeOffset);
}
return insnIndex;
}
......
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package invalid;
public class InvalidBytecodeOffset {
public final int f;
public InvalidBytecodeOffset(boolean b) {
this.f = b ? 1 : 0;
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package invalid;
public class InvalidClassVersion {}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package invalid;
public class InvalidConstantPoolIndex {}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package invalid;
public class InvalidCpInfoTag {}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package invalid;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.CLASS)
public @interface InvalidElementValue {}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package invalid;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE})
@interface Nullable {}
public class InvalidInsnTypeAnnotationTargetType {
public void method() {
@Nullable String local = null;
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package invalid;
public class InvalidOpcode {}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package invalid;
public class InvalidStackMapFrameType {
public InvalidStackMapFrameType(String s) {
}
public InvalidStackMapFrameType(boolean b) {
this(b ? "true" : "false");
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package invalid;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE})
@interface Nullable {}
public class InvalidTypeAnnotationTargetType {
public @Nullable String field;
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package invalid;
public class InvalidVerificationTypeInfo {
public InvalidVerificationTypeInfo(String s) {
}
public InvalidVerificationTypeInfo(boolean b) {
this(b ? "true" : "false");
}
}
......@@ -31,11 +31,12 @@ package jdk5;
* Class which, compiled with the JDK 1.5.0, produces the new JVM instructions from that version
* (compared to JDK 1.3.0). Also contain all the other instructions that can be used in JDK 1.5
* classes (which excludes jsr and ret), so that ASM classes which don't support jsr or ret (and
* therefore can't be tested with jdk3.AllIsntructions) can still be tested on all instructions.
* therefore can't be tested with jdk3.AllInstructions) can still be tested on all instructions.
* Must be compiled with "javac -g".
*/
class AllInstructions {
private Class c;
private Class d;
private int f;
private long g;
private AllInstructions field;
......@@ -48,6 +49,7 @@ class AllInstructions {
// New instruction in JDK 1.5.
public void ldcWithClassConstant() {
c = AllInstructions.class;
d = AllInstructions[].class;
}
public static int intInstructions(
......
......@@ -56,10 +56,11 @@ public class AllFrames {
// Frame types: same, same_locals_1_stack_item, full_frame.
// Element types: primitive types and object.
public int m0(boolean b, byte y, char c, short s, int i, float f, long l, double d, Object o) {
public int m0(boolean b, byte y, char c, short s, int i, float f, long l, double d, Object o,
Object[] p, Object[][] q) {
return b
? m0(!b, y, c, s, i - 1, f - 1f, l - 1l, d - 1d, o)
: m0(!b, y, c, s, i + 1, f + 1f, l + 1l, d + 1d, o);
? m0(!b, y, c, s, i - 1, f - 1f, l - 1l, d - 1d, o, p, q)
: m0(!b, y, c, s, i + 1, f + 1f, l + 1l, d + 1d, o, p, q);
}
// Frame types: append.
......@@ -132,7 +133,7 @@ public class AllFrames {
// Frame merges: two bi-dimensional arrays with mixed primitive / object type elements.
public static Object[] m10(boolean b) {
return b ? (Object[]) new byte[1][1] : (Object[]) new Float[1][1];
return b ? (Object[]) new byte[1][1] : (Object[]) new Float[1][];
}
// Frame merges: one and two dimensions arrays with identical element type.
......@@ -157,11 +158,36 @@ public class AllFrames {
// Frame merges: object type and single-dimensional array with primitive type elements.
public static Object m15(boolean b) {
return b ? new Integer(1) : new byte[1];
return b ? new Integer(1) : new char[1];
}
// Frame merges: object type and single-dimensional array with object type elements.
public static Object m16(boolean b) {
return b ? new Integer(1) : new Float[1];
}
// Frame merges: two single-dimensional arrays with different primitive type elements.
public Object m17(boolean b) {
return b ? new int[0] : new boolean[0];
}
// Frame merges: two single-dimensional arrays with different primitive type elements.
public Object m18(boolean b) {
return b ? new short[0] : new float[0];
}
// Frame merges: two single-dimensional arrays with different primitive type elements.
public Object m19(boolean b) {
return b ? new double[0] : new long[0];
}
// Frame merges: null type and object type.
public static Object m20(boolean b) {
return b ? null : new Integer(1);
}
// Frame merges: object type and null type.
public static Object m21(boolean b) {
return b ? new Integer(1) : null;
}
}
......@@ -32,7 +32,9 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import static org.objectweb.asm.test.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
/**
......@@ -42,13 +44,38 @@ import org.junit.jupiter.params.provider.MethodSource;
*/
public class AsmTestTest extends AsmTest {
/** Tests the isMoreRecentThan method. */
@ParameterizedTest
@MethodSource(ALL_CLASSES_AND_ALL_APIS)
public void testIsMoreRecentThan(PrecompiledClass classParameter, Api apiParameter) {
byte[] classContent = classParameter.getBytes();
int majorVersion = (classContent[6] & 0xFF) << 8 | (classContent[7] & 0xFF);
boolean isMoreRecent = classParameter.isMoreRecentThan(apiParameter);
switch (apiParameter) {
case ASM4:
assertEquals(majorVersion > /* V7 = */ 51, isMoreRecent);
break;
case ASM5:
assertEquals(majorVersion > /* V8 = */ 52, isMoreRecent);
break;
case ASM6:
assertEquals(majorVersion > /* V10 = */ 54, isMoreRecent);
break;
default:
fail("Unknown API value");
}
}
/** Tests that we can get the byte array content of each precompiled class. */
@ParameterizedTest
@MethodSource(ALL_CLASSES_AND_LATEST_API)
public void testGetBytes(PrecompiledClass classParameter, Api apiParameter) {
assertEquals(Api.ASM6, apiParameter);
assertEquals(0x00060000, apiParameter.value());
assertEquals("ASM6", apiParameter.toString());
assertThatClass(classParameter.getBytes()).contains(classParameter.getInternalName());
byte[] classContent = classParameter.getBytes();
assertThatClass(classContent).contains(classParameter.getInternalName());
assertThatClass(classContent).isEqualTo(classContent);
}
/** Tests that we can load (and instantiate) each (non-abstract) precompiled class. */
......@@ -171,4 +198,13 @@ public class AsmTestTest extends AsmTest {
}
assertEquals(1, occurrenceCount);
}
/** Tests that dumping an invalid class fails with an IOException. */
@ParameterizedTest
@EnumSource(InvalidClass.class)
public void testDumpInvalidClass(InvalidClass invalidClass) {
byte[] classContent = invalidClass.getBytes();
assertThrows(AssertionError.class, () -> assertThatClass(classContent).contains("invalid"));
assertThrows(AssertionError.class, () -> assertThatClass(classContent).isEqualTo(classContent));
}
}
......@@ -2439,16 +2439,6 @@ public class ClassReader {
// target_info field depends on the value of target_type.
int targetType = readInt(currentOffset);
switch (targetType >>> 24) {
case TypeReference.CLASS_TYPE_PARAMETER:
case TypeReference.METHOD_TYPE_PARAMETER:
case TypeReference.METHOD_FORMAL_PARAMETER:
currentOffset += 2;
break;
case TypeReference.FIELD: