static StackFrameType get(int frame_type) { if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { return SAME_FRAME; } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { return SAME_LOCALS_1_STACK_ITEM_FRAME; } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { return SAME_LOCALS_1_STACK_ITEM_FRAME; } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { return CHOP_FRAME; } else if (frame_type == Const.SAME_FRAME_EXTENDED) { return SAME_FRAME; } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { return APPEND_FRAME; } else if (frame_type == Const.FULL_FRAME) { return FULL_FRAME; } else { /* Can't happen */ throw new ClassFormatException("Invalid frame type : " + frame_type); } } }
throw new ClassFormatException("Unknown constant type " + tag);
/** * Get constant from constant pool. * * @param index Index in constant pool * @return Constant value * @see Constant */ public Constant getConstant( final int index ) { if (index >= constant_pool.length || index < 0) { throw new ClassFormatException("Invalid constant pool reference: " + index + ". Constant pool size is: " + constant_pool.length); } return constant_pool[index]; }
/** * Get constant from constant pool. * * @param index Index in constant pool * @return Constant value * @see Constant */ public Constant getConstant(int index) { if (index >= constant_pool.length || index < 0) throw new ClassFormatException("Invalid constant pool reference: " + index + ". Constant pool size is: " + constant_pool.length); return constant_pool[index]; }
/** * Check whether the header of the file is ok. * Of course, this has to be the first action on successive file reads. * @throws IOException * @throws ClassFormatException */ private void readID() throws IOException, ClassFormatException { if (dataInputStream.readInt() != Const.JVM_CLASSFILE_MAGIC) { throw new ClassFormatException(file_name + " is not a Java .class file"); } }
/** * Check whether the header of the file is ok. * Of course, this has to be the first action on successive file reads. * @throws IOException * @throws ClassFormatException */ private final void readID() throws IOException, ClassFormatException { int magic = 0xCAFEBABE; if(file.readInt() != magic) throw new ClassFormatException(file_name + " is not a Java .class file"); } /**
/** * Read information about the class and its super class. * @throws IOException * @throws ClassFormatException */ private void readClassInfo() throws IOException, ClassFormatException { access_flags = dataInputStream.readUnsignedShort(); /* Interfaces are implicitely abstract, the flag should be set * according to the JVM specification. */ if ((access_flags & Const.ACC_INTERFACE) != 0) { access_flags |= Const.ACC_ABSTRACT; } if (((access_flags & Const.ACC_ABSTRACT) != 0) && ((access_flags & Const.ACC_FINAL) != 0)) { throw new ClassFormatException("Class " + file_name + " can't be both final and abstract"); } class_name_index = dataInputStream.readUnsignedShort(); superclass_name_index = dataInputStream.readUnsignedShort(); }
/** * Read information about the class and its super class. * @throws IOException * @throws ClassFormatException */ private final void readClassInfo() throws IOException, ClassFormatException { access_flags = file.readUnsignedShort(); /* Interfaces are implicitely abstract, the flag should be set * according to the JVM specification. */ if((access_flags & Constants.ACC_INTERFACE) != 0) access_flags |= Constants.ACC_ABSTRACT; if(((access_flags & Constants.ACC_ABSTRACT) != 0) && ((access_flags & Constants.ACC_FINAL) != 0 )) throw new ClassFormatException("Class can't be both final and abstract"); class_name_index = file.readUnsignedShort(); superclass_name_index = file.readUnsignedShort(); } /**
/** * Return type of method signature as a byte value as defined in <em>Constants</em> * * @param signature in format described above * @return type of method signature * @see Constants */ public static final byte typeOfMethodSignature(String signature) throws ClassFormatException { int index; try { if(signature.charAt(0) != '(') throw new ClassFormatException("Invalid method signature: " + signature); index = signature.lastIndexOf(')') + 1; return typeOfSignature(signature.substring(index)); } catch(StringIndexOutOfBoundsException e) { throw new ClassFormatException("Invalid method signature: " + signature); } }
/** * Return type of method signature as a byte value as defined in <em>Constants</em> * * @param signature in format described above * @return type of method signature * @see Const * * @throws ClassFormatException if signature is not a method signature */ public static byte typeOfMethodSignature( final String signature ) throws ClassFormatException { int index; try { if (signature.charAt(0) != '(') { throw new ClassFormatException("Invalid method signature: " + signature); } index = signature.lastIndexOf(')') + 1; return typeOfSignature(signature.substring(index)); } catch (final StringIndexOutOfBoundsException e) { throw new ClassFormatException("Invalid method signature: " + signature, e); } }
/** * Convert return value of a method (signature) to a Type object. * * @param signature signature string such as (Ljava/lang/String;)V * @return return type */ public static Type getReturnType( final String signature ) { try { // Read return type after `)' final int index = signature.lastIndexOf(')') + 1; return getType(signature.substring(index)); } catch (final StringIndexOutOfBoundsException e) { // Should never occur throw new ClassFormatException("Invalid method signature: " + signature, e); } }
/** * Convert return value of a method (signature) to a Type object. * * @param signature signature string such as (Ljava/lang/String;)V * @return return type */ public static Type getReturnType(String signature) { try { // Read return type after `)' int index = signature.lastIndexOf(')') + 1; return getType(signature.substring(index)); } catch(StringIndexOutOfBoundsException e) { // Should never occur throw new ClassFormatException("Invalid method signature: " + signature); } }
/** * Convert arguments of a method (signature) to an array of Type objects. * @param signature signature string such as (Ljava/lang/String;)V * @return array of argument types */ public static Type[] getArgumentTypes(String signature) { ArrayList vec = new ArrayList(); int index; Type[] types; try { // Read all declarations between for `(' and `)' if(signature.charAt(0) != '(') throw new ClassFormatException("Invalid method signature: " + signature); index = 1; // current string position while(signature.charAt(index) != ')') { vec.add(getType(signature.substring(index))); index += consumed_chars; // update position } } catch(StringIndexOutOfBoundsException e) { // Should never occur throw new ClassFormatException("Invalid method signature: " + signature); } types = new Type[vec.size()]; vec.toArray(types); return types; }
/** * @param signature Method signature * @param chopit Shorten class names ? * @return return type of method * @throws ClassFormatException */ public static String methodSignatureReturnType( final String signature, final boolean chopit ) throws ClassFormatException { int index; String type; try { // Read return type after `)' index = signature.lastIndexOf(')') + 1; type = signatureToString(signature.substring(index), chopit); } catch (final StringIndexOutOfBoundsException e) { // Should never occur throw new ClassFormatException("Invalid method signature: " + signature, e); } return type; }
static int getArgumentTypesSize( final String signature ) { int res = 0; int index; try { // Read all declarations between for `(' and `)' if (signature.charAt(0) != '(') { throw new ClassFormatException("Invalid method signature: " + signature); } index = 1; // current string position while (signature.charAt(index) != ')') { final int coded = getTypeSize(signature.substring(index)); res += size(coded); index += consumed(coded); } } catch (final StringIndexOutOfBoundsException e) { // Should never occur throw new ClassFormatException("Invalid method signature: " + signature, e); } return res; }
/** * Get constant from constant pool and check whether it has the * expected type. * * @param index Index in constant pool * @param tag Tag of expected constant, i.e., its type * @return Constant value * @see Constant * @throws ClassFormatException */ public Constant getConstant( final int index, final byte tag ) throws ClassFormatException { Constant c; c = getConstant(index); if (c == null) { throw new ClassFormatException("Constant pool at index " + index + " is null."); } if (c.getTag() != tag) { throw new ClassFormatException("Expected class `" + Const.getConstantName(tag) + "' at index " + index + " and got " + c); } return c; }
/** * @param signature Method signature * @param chopit Shorten class names ? * @return return type of method * @throws ClassFormatException */ public static final String methodSignatureReturnType(String signature, boolean chopit) throws ClassFormatException { int index; String type; try { // Read return type after `)' index = signature.lastIndexOf(')') + 1; type = signatureToString(signature.substring(index), chopit); } catch(StringIndexOutOfBoundsException e) { // Should never occur throw new ClassFormatException("Invalid method signature: " + signature); } return type; }
static int getTypeSize( final String signature ) throws StringIndexOutOfBoundsException { final byte type = Utility.typeOfSignature(signature); if (type <= Const.T_VOID) { return encode(BasicType.getType(type).getSize(), 1); } else if (type == Const.T_ARRAY) { int dim = 0; do { // Count dimensions dim++; } while (signature.charAt(dim) == '['); // Recurse, but just once, if the signature is ok final int consumed = consumed(getTypeSize(signature.substring(dim))); return encode(1, dim + consumed); } else { // type == T_REFERENCE final int index = signature.indexOf(';'); // Look for closing `;' if (index < 0) { throw new ClassFormatException("Invalid signature: " + signature); } return encode(1, index + 1); } }
@Test public void testInitializeWithInvalidClassListShouldThrowClassFormatException() throws IOException { //GIVEN List<String> list = new ArrayList<>(); list.add(FOLDER_NAME); Collection<File> filesInFolder = new ArrayList<>(); File invalidClass = new File("InvalidClass.class"); filesInFolder.add(invalidClass); given(fileUtils.listFiles(FOLDER)).willReturn(filesInFolder); given(javaClassFactory.createJavaClass(invalidClass)).willThrow(new ClassFormatException()); Whitebox.setInternalState(underTest, "logger", logger); //WHEN underTest.initialize(list); //THEN verify(logger).info(Mockito.anyString(), Mockito.any(ClassFormatException.class)); }
@Test(expectedExceptions = CannotUploadExternalResourceException.class) public void testCreateFilePathShouldRethrowClassFormatExceptionAsCannotUploadExternalResourceException() throws IOException { //GIVEN given(fileFactory.createFile(FILE_NAME)).willReturn(file); given(file.getParent()).willReturn(PARENT_DIRECTORY); given(file.getName()).willReturn(SIMPLE_CLASS_NAME); given(javaClassFactory.createJavaClass(classFile, FILE_NAME)).willThrow(new ClassFormatException()); //WHEN underTest.createFilePath(classFile, FILE_NAME, EXCEPTION_MESSAGE); //THEN error is thrown } }