ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java
Status
scanned
Type
file
Name
ClassParser.java
Extension
.java
Programming language
Java
Mime type
text/html
File type
HTML document, ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
11447 (11.2 KB)
MD5
911e91beb51a120331b85c7b9c55b52d
SHA1
5af78ec974b74d0462f89070bb86b53e17fef1a3
SHA256
fcf126532b91ea87d551454c81a6d9c5524e252e5da376e511d9500a4a8f107b
SHA512

      
    
SHA1_git
ea5e61213cff1971fa6c71eb7ad1824964bbfd40
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
ClassParser.java | 11.2 KB |

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.tomcat.util.bcel.classfile; import java.io.BufferedInputStream; import java.io.DataInput; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.tomcat.util.bcel.Const; /** * Wrapper class that parses a given Java .class file. The method <a href="#parse">parse</a> returns a * <a href="JavaClass.html"> JavaClass</a> object on success. When an I/O error or an inconsistency occurs an * appropriate exception is propagated back to the caller. * * The structure and the names comply, except for a few conveniences, exactly with the * <a href="https://docs.oracle.com/javase/specs/"> JVM specification 1.0</a>. See this paper for further details about * the structure of a bytecode file. */ public final class ClassParser { private static final int BUFSIZE = 8192; private final DataInput dataInputStream; private String className; private String superclassName; private int accessFlags; // Access rights of parsed class private String[] interfaceNames; // Names of implemented interfaces private ConstantPool constantPool; // collection of constants private Annotations runtimeVisibleAnnotations; // "RuntimeVisibleAnnotations" attribute defined in the class private List<Annotations> runtimeVisibleFieldOrMethodAnnotations; // "RuntimeVisibleAnnotations" attribute defined elsewhere private static final String[] INTERFACES_EMPTY_ARRAY = {}; /** * Parses class from the given stream. * * @param inputStream Input stream */ public ClassParser(final InputStream inputStream) { this.dataInputStream = new DataInputStream(new BufferedInputStream(inputStream, BUFSIZE)); } /** * Parses the given Java class file and return an object that represents the contained data, i.e., constants, methods, * fields and commands. A <em>ClassFormatException</em> is raised, if the file is not a valid .class file. (This does * not include verification of the byte code as it is performed by the Java interpreter). * * @return Class object representing the parsed class file * @throws IOException if an I/O error occurs. * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ public JavaClass parse() throws IOException, ClassFormatException { //****************** Read headers ******************************** // Check magic tag of class file readID(); // Get compiler version readVersion(); //***************** Read constant pool and related ************** // Read constant pool entries readConstantPool(); // Get class information readClassInfo(); // Get interface information, i.e., implemented interfaces readInterfaces(); //***************** Read class fields and methods *************** // Read class fields, i.e., the variables of the class readFields(); // Read class methods, i.e., the functions in the class readMethods(); // Read class attributes readAttributes(false); // Return the information we have gathered in a new object return new JavaClass(className, superclassName, accessFlags, constantPool, interfaceNames, runtimeVisibleAnnotations, runtimeVisibleFieldOrMethodAnnotations); } /** * Reads information about the attributes of the class. * @param fieldOrMethod false if processing a class * @throws IOException if an I/O error occurs. * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readAttributes(boolean fieldOrMethod) throws IOException, ClassFormatException { final int attributesCount = dataInputStream.readUnsignedShort(); for (int i = 0; i < attributesCount; i++) { ConstantUtf8 c; String name; int name_index; int length; // Get class name from constant pool via 'name_index' indirection name_index = dataInputStream.readUnsignedShort(); c = (ConstantUtf8) constantPool.getConstant(name_index, Const.CONSTANT_Utf8); name = c.getBytes(); // Length of data in bytes length = dataInputStream.readInt(); if (name.equals("RuntimeVisibleAnnotations")) { if (fieldOrMethod) { Annotations fieldOrMethodAnnotations = new Annotations(dataInputStream, constantPool); if (runtimeVisibleFieldOrMethodAnnotations == null) { runtimeVisibleFieldOrMethodAnnotations = new ArrayList<>(); } runtimeVisibleFieldOrMethodAnnotations.add(fieldOrMethodAnnotations); } else { if (runtimeVisibleAnnotations != null) { throw new ClassFormatException( "RuntimeVisibleAnnotations attribute is not allowed more than once in a class file"); } runtimeVisibleAnnotations = new Annotations(dataInputStream, constantPool); } } else { // All other attributes are skipped Utility.skipFully(dataInputStream, length); } } } /** * Reads information about the class and its super class. * * @throws IOException if an I/O error occurs. * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readClassInfo() throws IOException, ClassFormatException { accessFlags = dataInputStream.readUnsignedShort(); /* * Interfaces are implicitly abstract, the flag should be set according to the JVM specification. */ if ((accessFlags & Const.ACC_INTERFACE) != 0) { accessFlags |= Const.ACC_ABSTRACT; } if ((accessFlags & Const.ACC_ABSTRACT) != 0 && (accessFlags & Const.ACC_FINAL) != 0) { throw new ClassFormatException("Class can't be both final and abstract"); } int classNameIndex = dataInputStream.readUnsignedShort(); className = Utility.getClassName(constantPool, classNameIndex); int superclass_name_index = dataInputStream.readUnsignedShort(); if (superclass_name_index > 0) { // May be zero -> class is java.lang.Object superclassName = Utility.getClassName(constantPool, superclass_name_index); } else { superclassName = "java.lang.Object"; } } /** * Reads constant pool entries. * * @throws IOException if an I/O error occurs. * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readConstantPool() throws IOException, ClassFormatException { constantPool = new ConstantPool(dataInputStream); } /** * Reads information about the fields of the class, i.e., its variables. * * @throws IOException if an I/O error occurs. * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readFields() throws IOException, ClassFormatException { final int fieldsCount = dataInputStream.readUnsignedShort(); for (int i = 0; i < fieldsCount; i++) { // file.readUnsignedShort(); // Unused access flags // file.readUnsignedShort(); // name index // file.readUnsignedShort(); // signature index Utility.skipFully(dataInputStream, 6); readAttributes(true); } } /** * Checks whether the header of the file is ok. Of course, this has to be the first action on successive file reads. * * @throws IOException if an I/O error occurs. * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readID() throws IOException, ClassFormatException { if (dataInputStream.readInt() != Const.JVM_CLASSFILE_MAGIC) { throw new ClassFormatException("It is not a Java .class file"); } } /** * Reads information about the interfaces implemented by this class. * * @throws IOException if an I/O error occurs. * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readInterfaces() throws IOException, ClassFormatException { final int interfacesCount = dataInputStream.readUnsignedShort(); if (interfacesCount > 0) { interfaceNames = new String[interfacesCount]; for (int i = 0; i < interfacesCount; i++) { int index = dataInputStream.readUnsignedShort(); interfaceNames[i] = Utility.getClassName(constantPool, index); } } else { interfaceNames = INTERFACES_EMPTY_ARRAY; } } /** * Reads information about the methods of the class. * * @throws IOException if an I/O error occurs. * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readMethods() throws IOException, ClassFormatException { final int methodsCount = dataInputStream.readUnsignedShort(); for (int i = 0; i < methodsCount; i++) { // file.readUnsignedShort(); // Unused access flags // file.readUnsignedShort(); // name index // file.readUnsignedShort(); // signature index Utility.skipFully(dataInputStream, 6); readAttributes(true); } } /** * Reads major and minor version of compiler which created the file. * * @throws IOException if an I/O error occurs. * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readVersion() throws IOException, ClassFormatException { // file.readUnsignedShort(); // Unused minor // file.readUnsignedShort(); // Unused major Utility.skipFully(dataInputStream, 4); } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
11.05
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9
https://docs.oracle.com/javase/specs/ 35 35