/** * Creates a class reader for the given binary representation of a class file. * * @param binaryRepresentation The binary representation of a class file to read. * @return An appropriate class reader. */ public static ClassReader of(byte[] binaryRepresentation) { if (EXPERIMENTAL) { byte[] actualVersion = new byte[]{binaryRepresentation[4], binaryRepresentation[5], binaryRepresentation[6], binaryRepresentation[7]}; binaryRepresentation[4] = (byte) (Opcodes.V11 >>> 24); binaryRepresentation[5] = (byte) (Opcodes.V11 >>> 16); binaryRepresentation[6] = (byte) (Opcodes.V11 >>> 8); binaryRepresentation[7] = (byte) Opcodes.V11; ClassReader classReader = new ClassReader(binaryRepresentation); System.arraycopy(actualVersion, 0, binaryRepresentation, 4, actualVersion.length); return classReader; } else { return new ClassReader(binaryRepresentation); } } }
/** * Makes the given visitor visit the JVMS ClassFile structure passed to the constructor of this * {@link ClassReader}. * * @param classVisitor the visitor that must visit this class. * @param parsingOptions the options to use to parse this class. One or more of {@link * #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_FRAMES} or {@link #EXPAND_FRAMES}. */ public void accept(final ClassVisitor classVisitor, final int parsingOptions) { accept(classVisitor, new Attribute[0], parsingOptions); }
int[] typeAnnotationsOffsets = new int[readUnsignedShort(currentOffset)]; currentOffset += 2; int targetType = readInt(currentOffset); switch (targetType >>> 24) { case TypeReference.LOCAL_VARIABLE: int tableLength = readUnsignedShort(currentOffset + 1); currentOffset += 3; while (tableLength-- > 0) { int startPc = readUnsignedShort(currentOffset); int length = readUnsignedShort(currentOffset + 2); createLabel(startPc, context.currentMethodLabels); createLabel(startPc + length, context.currentMethodLabels); int pathLength = readByte(currentOffset); if ((targetType >>> 24) == TypeReference.EXCEPTION_PARAMETER) { String annotationDescriptor = readUTF8(currentOffset, charBuffer); currentOffset += 2; readElementValues( methodVisitor.visitTryCatchAnnotation( targetType & 0xFFFFFF00, path, annotationDescriptor, visible), readElementValues( /* annotationVisitor = */ null, currentOffset, /* named = */ true, charBuffer);
int currentAttributeOffset = getFirstAttributeOffset(); int[] currentBootstrapMethodOffsets = null; for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) { String attributeName = readUTF8(currentAttributeOffset, charBuffer); int attributeLength = readInt(currentAttributeOffset + 2); currentAttributeOffset += 6; if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) { currentBootstrapMethodOffsets = new int[readUnsignedShort(currentAttributeOffset)]; 4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
offsetDelta = frameType - Frame.SAME_LOCALS_1_STACK_ITEM_FRAME; currentOffset = readVerificationTypeInfo( currentOffset, context.currentFrameStackTypes, 0, charBuffer, labels); context.currentFrameType = Opcodes.F_SAME1; context.currentFrameStackCount = 1; } else if (frameType >= Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { offsetDelta = readUnsignedShort(currentOffset); currentOffset += 2; if (frameType == Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { currentOffset = readVerificationTypeInfo( currentOffset, context.currentFrameStackTypes, 0, charBuffer, labels); context.currentFrameType = Opcodes.F_SAME1; for (int k = frameType - Frame.SAME_FRAME_EXTENDED; k > 0; k--) { currentOffset = readVerificationTypeInfo( currentOffset, context.currentFrameLocalTypes, local++, charBuffer, labels); context.currentFrameStackCount = 0; } else { final int numberOfLocals = readUnsignedShort(currentOffset); currentOffset += 2; context.currentFrameType = Opcodes.F_FULL; for (int local = 0; local < numberOfLocals; ++local) { currentOffset = readVerificationTypeInfo(
break; case Frame.ITEM_OBJECT: frame[index] = readClass(currentOffset, charBuffer); currentOffset += 2; break; case Frame.ITEM_UNINITIALIZED: frame[index] = createLabel(readUnsignedShort(currentOffset), labels); currentOffset += 2; break;
final int maxStack = readUnsignedShort(currentOffset); final int maxLocals = readUnsignedShort(currentOffset + 2); final int codeLength = readInt(currentOffset + 4); currentOffset += 8; case Constants.IFNULL: case Constants.IFNONNULL: createLabel(bytecodeOffset + readShort(currentOffset + 1), labels); currentOffset += 3; break; case Constants.ASM_IFNULL: case Constants.ASM_IFNONNULL: createLabel(bytecodeOffset + readUnsignedShort(currentOffset + 1), labels); currentOffset += 3; break; case Constants.JSR_W: case Constants.ASM_GOTO_W: createLabel(bytecodeOffset + readInt(currentOffset + 1), labels); currentOffset += 5; break; createLabel(bytecodeOffset + readInt(currentOffset), labels); int numTableEntries = readInt(currentOffset + 8) - readInt(currentOffset + 4) + 1; currentOffset += 12; createLabel(bytecodeOffset + readInt(currentOffset), labels); currentOffset += 4;
int accessFlags = readUnsignedShort(currentOffset); String thisClass = readClass(currentOffset + 2, charBuffer); String superClass = readClass(currentOffset + 4, charBuffer); String[] interfaces = new String[readUnsignedShort(currentOffset + 6)]; currentOffset += 8; for (int i = 0; i < interfaces.length; ++i) { interfaces[i] = readClass(currentOffset, charBuffer); currentOffset += 2; int currentAttributeOffset = getFirstAttributeOffset(); for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) { String attributeName = readUTF8(currentAttributeOffset, charBuffer); int attributeLength = readInt(currentAttributeOffset + 2); currentAttributeOffset += 6; sourceFile = readUTF8(currentAttributeOffset, charBuffer); } else if (Constants.INNER_CLASSES.equals(attributeName)) { innerClassesOffset = currentAttributeOffset; enclosingMethodOffset = currentAttributeOffset; } else if (Constants.NEST_HOST.equals(attributeName)) { nestHostClass = readClass(currentAttributeOffset, charBuffer); } else if (Constants.NEST_MEMBERS.equals(attributeName)) { nestMembersOffset = currentAttributeOffset; } else if (Constants.SIGNATURE.equals(attributeName)) { signature = readUTF8(currentAttributeOffset, charBuffer); } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) { runtimeVisibleAnnotationsOffset = currentAttributeOffset;
int constantPoolOffset = classReader.getItem(1) - 1; int constantPoolLength = classReader.header - constantPoolOffset; constantPoolCount = classReader.getItemCount(); constantPool = new ByteVector(constantPoolLength); constantPool.putByteArray(inputBytes, constantPoolOffset, constantPoolLength); char[] charBuffer = new char[classReader.getMaxStringLength()]; boolean hasBootstrapMethods = false; int itemIndex = 1; while (itemIndex < constantPoolCount) { int itemOffset = classReader.getItem(itemIndex); int itemTag = inputBytes[itemOffset - 1]; int nameAndTypeItemOffset; case Symbol.CONSTANT_INTERFACE_METHODREF_TAG: nameAndTypeItemOffset = classReader.getItem(classReader.readUnsignedShort(itemOffset + 2)); addConstantMemberReference( itemIndex, itemTag, classReader.readClass(itemOffset, charBuffer), classReader.readUTF8(nameAndTypeItemOffset, charBuffer), classReader.readUTF8(nameAndTypeItemOffset + 2, charBuffer)); break; case Symbol.CONSTANT_INTEGER_TAG: case Symbol.CONSTANT_FLOAT_TAG: addConstantIntegerOrFloat(itemIndex, itemTag, classReader.readInt(itemOffset)); break; case Symbol.CONSTANT_NAME_AND_TYPE_TAG:
firstAttribute = null; compute = hasFrames ? MethodWriter.COMPUTE_INSERTED_FRAMES : MethodWriter.COMPUTE_NOTHING; new ClassReader(classFile, 0, /* checkClassVersion = */ false) .accept( this, attributes,
int currentOffset = typeAnnotationOffset; int targetType = readInt(typeAnnotationOffset); switch (targetType >>> 24) { case TypeReference.CLASS_TYPE_PARAMETER: case TypeReference.RESOURCE_VARIABLE: targetType &= 0xFF000000; int tableLength = readUnsignedShort(currentOffset + 1); currentOffset += 3; context.currentLocalVariableAnnotationRangeStarts = new Label[tableLength]; context.currentLocalVariableAnnotationRangeIndices = new int[tableLength]; for (int i = 0; i < tableLength; ++i) { int startPc = readUnsignedShort(currentOffset); int length = readUnsignedShort(currentOffset + 2); int index = readUnsignedShort(currentOffset + 4); currentOffset += 6; context.currentLocalVariableAnnotationRangeStarts[i] = createLabel(startPc, context.currentMethodLabels); context.currentLocalVariableAnnotationRangeEnds[i] = createLabel(startPc + length, context.currentMethodLabels); context.currentLocalVariableAnnotationRangeIndices[i] = index; int pathLength = readByte(currentOffset); context.currentTypeAnnotationTargetPath = pathLength == 0 ? null : new TypePath(b, currentOffset);
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (loader == null || shouldIgnore(className)) { return null; } final ClassReader reader = new ClassReader(classfileBuffer); final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); reader.accept(new PowerMockClassVisitor(writer), ClassReader.SKIP_FRAMES); return writer.toByteArray(); }
int currentAttributeOffset = classReader.getFirstAttributeOffset(); for (int i = classReader.readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) { String attributeName = classReader.readUTF8(currentAttributeOffset, charBuffer); if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) { bootstrapMethodCount = classReader.readUnsignedShort(currentAttributeOffset + 6); break; currentAttributeOffset += 6 + classReader.readInt(currentAttributeOffset + 2); int bootstrapMethodsLength = classReader.readInt(currentAttributeOffset + 2) - 2; bootstrapMethods = new ByteVector(bootstrapMethodsLength); bootstrapMethods.putByteArray(inputBytes, bootstrapMethodsOffset, bootstrapMethodsLength); for (int i = 0; i < bootstrapMethodCount; i++) { int offset = currentOffset - bootstrapMethodsOffset; int bootstrapMethodRef = classReader.readUnsignedShort(currentOffset); currentOffset += 2; int numBootstrapArguments = classReader.readUnsignedShort(currentOffset); currentOffset += 2; int hashCode = classReader.readConst(bootstrapMethodRef, charBuffer).hashCode(); while (numBootstrapArguments-- > 0) { int bootstrapArgument = classReader.readUnsignedShort(currentOffset); currentOffset += 2; hashCode ^= classReader.readConst(bootstrapArgument, charBuffer).hashCode();
for (String className : listAllJavaClasses(hookJars, classNameFilter)) { byte[] binaryRepresentation = readBinaryRepresentation(className); ClassReader classReader = new ClassReader(binaryRepresentation); HookMetadataBuilder hookMetadata = new HookMetadataBuilder(className); classReader.accept(new ClassVisitor(Opcodes.ASM5) { @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
/** * {@inheritDoc} */ public void apply() { classReader.accept(this, ClassReader.SKIP_DEBUG | stackMapFrameHandler.getReaderHint()); }
/** * {@inheritDoc} */ public void prepare() { classReader.accept(new ExceptionTableExtractor(), ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); suppressionHandler.onPrepare(methodVisitor); }
/** * Parses a binary representation and transforms it into a type description. * * @param binaryRepresentation The binary data to be parsed. * @return A type description of the binary data. */ private TypeDescription parse(byte[] binaryRepresentation) { ClassReader classReader = OpenedClassReader.of(binaryRepresentation); TypeExtractor typeExtractor = new TypeExtractor(); classReader.accept(typeExtractor, readerMode.getFlags()); return typeExtractor.toTypeDescription(); }
/** * Extracts a class' class version. * * @param typeDescription The type for which to locate a class file version. * @param classFileLocator The class file locator to query for a class file. * @return The type's class file version. * @throws IOException If an error occurs while reading the class file. */ public static ClassFileVersion of(TypeDescription typeDescription, ClassFileLocator classFileLocator) throws IOException { ClassReader classReader = OpenedClassReader.of(classFileLocator.locate(typeDescription.getName()).resolve()); VersionExtractor versionExtractor = new VersionExtractor(); classReader.accept(versionExtractor, ClassReader.SKIP_CODE); return ClassFileVersion.ofMinorMajor(versionExtractor.getClassFileVersionNumber()); }
@Override protected UnresolvedType create(TypeInitializer typeInitializer) { try { int writerFlags = asmVisitorWrapper.mergeWriter(AsmVisitorWrapper.NO_FLAGS); int readerFlags = asmVisitorWrapper.mergeReader(AsmVisitorWrapper.NO_FLAGS); byte[] binaryRepresentation = classFileLocator.locate(originalType.getName()).resolve(); ClassDumpAction.dump(DUMP_FOLDER, instrumentedType, true, binaryRepresentation); ClassReader classReader = OpenedClassReader.of(binaryRepresentation); ClassWriter classWriter = classWriterStrategy.resolve(writerFlags, typePool, classReader); ContextRegistry contextRegistry = new ContextRegistry(); classReader.accept(writeTo(ValidatingClassVisitor.of(classWriter, typeValidation), typeInitializer, contextRegistry, writerFlags, readerFlags), readerFlags); return new UnresolvedType(classWriter.toByteArray(), contextRegistry.getAuxiliaryTypes()); } catch (IOException exception) { throw new RuntimeException("The class file could not be written", exception); } }