⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pass3averifier.java

📁 该开源工具主要用于class文件的操作
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
					throw new StaticCodeInstructionOperandConstraintException("Due to JustIce's clear definition of subroutines, no JSR or JSR_W may have a top-level instruction (such as the very first instruction, which is targeted by instruction '"+ih+"' as its target.");				}				if (!(target.getInstruction() instanceof ASTORE)){					throw new StaticCodeInstructionOperandConstraintException("Due to JustIce's clear definition of subroutines, no JSR or JSR_W may target anything else than an ASTORE instruction. Instruction '"+ih+"' targets '"+target+"'.");				}			}						// vmspec2, page 134-137			ih.accept(v);						ih = ih.getNext();		}	}		/** A small utility method returning if a given int i is in the given int[] ints. */	private static boolean contains(int[] ints, int i){		for (int j=0; j<ints.length; j++){			if (ints[j]==i) return true;		}		return false;	}	/** Returns the method number as supplied when instantiating. */	public int getMethodNo(){		return method_no;	}	/**	 * This visitor class does the actual checking for the instruction	 * operand's constraints.	 */	private class InstOperandConstraintVisitor extends org.apache.bcel.generic.EmptyVisitor{		/** The ConstantPoolGen instance this Visitor operates on. */		private ConstantPoolGen cpg;		/** The only Constructor. */		InstOperandConstraintVisitor(ConstantPoolGen cpg){			this.cpg = cpg;		}		/**		 * Utility method to return the max_locals value of the method verified		 * by the surrounding Pass3aVerifier instance.		 */		private int max_locals(){			return Repository.lookupClass(myOwner.getClassName()).getMethods()[method_no].getCode().getMaxLocals();		}		/**		 * A utility method to always raise an exeption.		 */		private void constraintViolated(Instruction i, String message) {			throw new StaticCodeInstructionOperandConstraintException("Instruction "+i+" constraint violated: "+message);		}		/**		 * A utility method to raise an exception if the index is not		 * a valid constant pool index.		 */		private void indexValid(Instruction i, int idx){			if (idx < 0 || idx >= cpg.getSize()){				constraintViolated(i, "Illegal constant pool index '"+idx+"'.");			}		}		///////////////////////////////////////////////////////////		// The Java Virtual Machine Specification, pages 134-137 //		///////////////////////////////////////////////////////////		/**		 * Assures the generic preconditions of a LoadClass instance.		 * The referenced class is loaded and pass2-verified.		 */		public void visitLoadClass(LoadClass o){			ObjectType t = o.getLoadClassType(cpg);			if (t != null){// null means "no class is loaded"				Verifier v = VerifierFactory.getVerifier(t.getClassName());				VerificationResult vr = v.doPass1();				if (vr.getStatus() != VerificationResult.VERIFIED_OK){					constraintViolated((Instruction) o, "Class '"+o.getLoadClassType(cpg).getClassName()+"' is referenced, but cannot be loaded: '"+vr+"'.");				}			}		}				// The target of each jump and branch instruction [...] must be the opcode [...]		// BCEL _DOES_ handle this.		// tableswitch: BCEL will do it, supposedly.				// lookupswitch: BCEL will do it, supposedly.				/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		// LDC and LDC_W (LDC_W is a subclass of LDC in BCEL's model)		public void visitLDC(LDC o){			indexValid(o, o.getIndex());			Constant c = cpg.getConstant(o.getIndex());			if (! ( (c instanceof ConstantInteger)	||							(c instanceof ConstantFloat) 		||							(c instanceof ConstantString) ) ){				constraintViolated(o, "Operand of LDC or LDC_W must be one of CONSTANT_Integer, CONSTANT_Float or CONSTANT_String, but is '"+c+"'.");			}		}		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		// LDC2_W		public void visitLDC2_W(LDC2_W o){			indexValid(o, o.getIndex());			Constant c = cpg.getConstant(o.getIndex());			if (! ( (c instanceof ConstantLong)	||							(c instanceof ConstantDouble) ) ){				constraintViolated(o, "Operand of LDC2_W must be CONSTANT_Long or CONSTANT_Double, but is '"+c+"'.");			}			try{				indexValid(o, o.getIndex()+1);			}			catch(StaticCodeInstructionOperandConstraintException e){				throw new AssertionViolatedException("OOPS: Does not BCEL handle that? LDC2_W operand has a problem.");			}		}		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */ 		//getfield, putfield, getstatic, putstatic 		public void visitFieldInstruction(FieldInstruction o){			indexValid(o, o.getIndex());			Constant c = cpg.getConstant(o.getIndex());			if (! (c instanceof ConstantFieldref)){				constraintViolated(o, "Indexing a constant that's not a CONSTANT_Fieldref but a '"+c+"'.");			}		}			/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitInvokeInstruction(InvokeInstruction o){			indexValid(o, o.getIndex());			if (	(o instanceof INVOKEVIRTUAL)	||						(o instanceof INVOKESPECIAL)	||						(o instanceof INVOKESTATIC)	){				Constant c = cpg.getConstant(o.getIndex());				if (! (c instanceof ConstantMethodref)){					constraintViolated(o, "Indexing a constant that's not a CONSTANT_Methodref but a '"+c+"'.");				}				else{					// Constants are okay due to pass2.					ConstantNameAndType cnat = (ConstantNameAndType) (cpg.getConstant(((ConstantMethodref) c).getNameAndTypeIndex()));					ConstantUtf8 cutf8 = (ConstantUtf8) (cpg.getConstant(cnat.getNameIndex()));					if (cutf8.getBytes().equals(Constants.CONSTRUCTOR_NAME) && (!(o instanceof INVOKESPECIAL)) ){						constraintViolated(o, "Only INVOKESPECIAL is allowed to invoke instance initialization methods.");					}					if ( (! (cutf8.getBytes().equals(Constants.CONSTRUCTOR_NAME)) ) && (cutf8.getBytes().startsWith("<")) ){						constraintViolated(o, "No method with a name beginning with '<' other than the instance initialization methods may be called by the method invocation instructions.");					}				}			}			else{ //if (o instanceof INVOKEINTERFACE){				Constant c = cpg.getConstant(o.getIndex());				if (! (c instanceof ConstantInterfaceMethodref)){					constraintViolated(o, "Indexing a constant that's not a CONSTANT_InterfaceMethodref but a '"+c+"'.");				}				// TODO: From time to time check if BCEL allows to detect if the				// 'count' operand is consistent with the information in the				// CONSTANT_InterfaceMethodref and if the last operand is zero.				// By now, BCEL hides those two operands because they're superfluous.								// Invoked method must not be <init> or <clinit>				ConstantNameAndType cnat = (ConstantNameAndType) (cpg.getConstant(((ConstantInterfaceMethodref)c).getNameAndTypeIndex()));				String name = ((ConstantUtf8) (cpg.getConstant(cnat.getNameIndex()))).getBytes();				if (name.equals(Constants.CONSTRUCTOR_NAME)){					constraintViolated(o, "Method to invoke must not be '"+Constants.CONSTRUCTOR_NAME+"'.");				}				if (name.equals(Constants.STATIC_INITIALIZER_NAME)){					constraintViolated(o, "Method to invoke must not be '"+Constants.STATIC_INITIALIZER_NAME+"'.");				}			}					// The LoadClassType is the method-declaring class, so we have to check the other types.						Type t = o.getReturnType(cpg);			if (t instanceof ArrayType){				t = ((ArrayType) t).getBasicType();			}			if (t instanceof ObjectType){				Verifier v = VerifierFactory.getVerifier(((ObjectType) t).getClassName());				VerificationResult vr = v.doPass2();				if (vr.getStatus() != VerificationResult.VERIFIED_OK){					constraintViolated(o, "Return type class/interface could not be verified successfully: '"+vr.getMessage()+"'.");				}			}						Type[] ts = o.getArgumentTypes(cpg);			for (int i=0; i<ts.length; i++){				t = ts[i];				if (t instanceof ArrayType){					t = ((ArrayType) t).getBasicType();				}				if (t instanceof ObjectType){					Verifier v = VerifierFactory.getVerifier(((ObjectType) t).getClassName());					VerificationResult vr = v.doPass2();					if (vr.getStatus() != VerificationResult.VERIFIED_OK){						constraintViolated(o, "Argument type class/interface could not be verified successfully: '"+vr.getMessage()+"'.");					}				}			}					}				/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitINSTANCEOF(INSTANCEOF o){			indexValid(o, o.getIndex());			Constant c = cpg.getConstant(o.getIndex());			if (!	(c instanceof ConstantClass)){				constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'.");			}		}		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitCHECKCAST(CHECKCAST o){			indexValid(o, o.getIndex());			Constant c = cpg.getConstant(o.getIndex());			if (!	(c instanceof ConstantClass)){				constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'.");			}		}		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitNEW(NEW o){			indexValid(o, o.getIndex());			Constant c = cpg.getConstant(o.getIndex());			if (!	(c instanceof ConstantClass)){				constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'.");			}			else{				ConstantUtf8 cutf8 = (ConstantUtf8) (cpg.getConstant( ((ConstantClass) c).getNameIndex() ));				Type t = Type.getType("L"+cutf8.getBytes()+";");				if (t instanceof ArrayType){					constraintViolated(o, "NEW must not be used to create an array.");				}			}					}		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitMULTIANEWARRAY(MULTIANEWARRAY o){			indexValid(o, o.getIndex());			Constant c = cpg.getConstant(o.getIndex());			if (!	(c instanceof ConstantClass)){				constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'.");			}			int dimensions2create = o.getDimensions();			if (dimensions2create < 1){				constraintViolated(o, "Number of dimensions to create must be greater than zero.");			}			Type t = o.getType(cpg);			if (t instanceof ArrayType){				int dimensions = ((ArrayType) t).getDimensions();				if (dimensions < dimensions2create){					constraintViolated(o, "Not allowed to create array with more dimensions ('+dimensions2create+') than the one referenced by the CONSTANT_Class '"+t+"'.");				}			}			else{				constraintViolated(o, "Expecting a CONSTANT_Class referencing an array type. [Constraint not found in The Java Virtual Machine Specification, Second Edition, 4.8.1]");			}		}		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitANEWARRAY(ANEWARRAY o){			indexValid(o, o.getIndex());			Constant c = cpg.getConstant(o.getIndex());			if (!	(c instanceof ConstantClass)){				constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'.");			}			Type t = o.getType(cpg);			if (t instanceof ArrayType){				int dimensions = ((ArrayType) t).getDimensions();				if (dimensions >= 255){					constraintViolated(o, "Not allowed to create an array with more than 255 dimensions.");				}			}		}		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitNEWARRAY(NEWARRAY o){			byte t = o.getTypecode();			if (!	(	(t == Constants.T_BOOLEAN)	||							(t == Constants.T_CHAR)			||							(t == Constants.T_FLOAT)		||							(t == Constants.T_DOUBLE)		||							(t == Constants.T_BYTE)			||							(t == Constants.T_SHORT)		||							(t == Constants.T_INT)			||							(t == Constants.T_LONG)	)	){				constraintViolated(o, "Illegal type code '+t+' for 'atype' operand.");			}		}		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitILOAD(ILOAD o){			int idx = o.getIndex();			if (idx < 0){				constraintViolated(o, "Index '"+idx+"' must be non-negative.");			}			else{				int maxminus1 =  max_locals()-1;				if (idx > maxminus1){					constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'.");				}			}		}		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitFLOAD(FLOAD o){			int idx = o.getIndex();			if (idx < 0){				constraintViolated(o, "Index '"+idx+"' must be non-negative.");			}			else{				int maxminus1 =  max_locals()-1;				if (idx > maxminus1){					constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'.");				}			}		}		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitALOAD(ALOAD o){			int idx = o.getIndex();			if (idx < 0){				constraintViolated(o, "Index '"+idx+"' must be non-negative.");			}			else{				int maxminus1 =  max_locals()-1;				if (idx > maxminus1){					constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'.");				}			}		}				/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitISTORE(ISTORE o){			int idx = o.getIndex();			if (idx < 0){				constraintViolated(o, "Index '"+idx+"' must be non-negative.");			}			else{				int maxminus1 =  max_locals()-1;				if (idx > maxminus1){					constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'.");				}			}		}				/** Checks if the constraints of operands of the said instruction(s) are satisfied. */		public void visitFSTORE(FSTORE o){			int idx = o.getIndex();			if (idx < 0){				constraintViolated(o, "Index '"+idx+"' must be non-negative.");			}			else{				int maxminus1 =  max_locals()-1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -