@Override public void execute(ExecutionNode node, MethodState mState) { HeapItem arrayItem = mState.readRegister(arrayRegister); Object array = arrayItem.getValue(); Object lengthValue = null; if (arrayItem.isUnknown()) { lengthValue = new UnknownValue(); } else if (array == null) { node.clearChildren(); return; } else if (array.getClass().isArray()) { lengthValue = Array.getLength(array); node.clearExceptions(); } else { // Won't pass DEX verifier if it's not an array class. Probably our fault, so error. if (log.isErrorEnabled()) { log.error("Unexpected non-array class: {}, {}", array.getClass(), array); } } mState.assignRegister(destRegister, lengthValue, CommonTypes.INTEGER); }
public static void verifyExceptionHandling(Set<Throwable> expectedExceptions, ExecutionNode node, MethodState mState) { verify(node).setExceptions(eq(expectedExceptions)); verify(node).clearChildren(); verify(node, times(0)).setChildLocations(any(MethodLocation[].class)); verify(mState, times(0)).assignRegister(any(Integer.class), any(HeapItem.class)); }
public static void verifyExceptionHandling(Class<? extends Throwable> exceptionClass, String message, ExecutionNode node, MethodState mState) { ArgumentCaptor<Throwable> argument = ArgumentCaptor.forClass(Throwable.class); verify(node).setException(argument.capture()); assertEquals(exceptionClass, argument.getValue().getClass()); assertEquals(message, argument.getValue().getMessage()); verify(node).clearChildren(); verify(node, times(0)).setChildLocations(any(MethodLocation[].class)); verify(mState, times(0)).assignRegister(any(Integer.class), any(HeapItem.class)); }
private void executeArrayClone(MethodState callerMethodState, ExecutionNode node) { int instanceRegister = parameterRegisters[0]; HeapItem arrayItem = callerMethodState.peekRegister(instanceRegister); if (arrayItem.isUnknown()) { callerMethodState.assignResultRegister(new UnknownValue(), arrayItem.getType()); } else if (arrayItem.isNull()) { // This operation would have thrown a null pointer exception, and nothing else. Throwable exception = new NullPointerException(); addException(exception); node.clearChildren(); } else { Method m = null; try { m = Object.class.getDeclaredMethod("clone"); m.setAccessible(true); Object clone = m.invoke(arrayItem.getValue()); callerMethodState.assignResultRegister(clone, arrayItem.getType()); } catch (Exception e) { // TODO: should handle exceptions here and bubble them up e.printStackTrace(); } } }
@Override public void execute(ExecutionNode node, MethodState mState) { Object constant = buildConstant(); if (constant instanceof Throwable) { node.setException((Throwable) constant); node.clearChildren(); return; } else { node.clearExceptions(); } mState.assignRegister(destRegister, constant, getConstantTypeString()); }
@Override public void execute(ExecutionNode node, MethodState mState) { HeapItem lengthItem = mState.readRegister(lengthRegister); Object instance = buildInstance(lengthItem); if (instance instanceof Throwable) { node.setException((Throwable) instance); node.clearChildren(); return; } else { node.clearExceptions(); } mState.assignRegister(destRegister, instance, arrayType); }
Throwable exception = exceptionFactory.build(this, NullPointerException.class); node.setException(exception); node.clearChildren(); return; Throwable exception = exceptionFactory.build(this, ArrayIndexOutOfBoundsException.class); node.setException(exception); node.clearChildren(); return; } else {
Throwable exception = exceptionFactory.build(this, ArrayStoreException.class, storeType); node.setException(exception); node.clearChildren(); return; Throwable exception = exceptionFactory.build(this, NullPointerException.class); node.setException(exception); node.clearChildren(); return; Throwable exception = exceptionFactory.build(this, ArrayIndexOutOfBoundsException.class); node.setException(exception); node.clearChildren(); return; } else {
node.clearChildren(); } else { if (!method.getReturnType().equals(CommonTypes.VOID)) {
@Override public void execute(ExecutionNode node, MethodState mState) { HeapItem item = mState.readRegister(targetRegister); boolean isInstance = isInstance(item, castType, classManager); if (isInstance) { node.clearExceptions(); mState.assignRegister(targetRegister, item.getValue(), castType.getName()); } else { // E.g. java.lang.ClassCastException: java.lang.String cannot be cast to java.io.File String error = ClassNameUtils.internalToBinary(item.getType()) + " cannot be cast to " + castType.getBinaryName(); Throwable exception = exceptionFactory.build(this, ClassCastException.class, error); node.setException(exception); if (!item.isUnknown()) { // Exception is certain to happen since we had all class information // exception is certain. node.clearChildren(); } } }
sideEffectLevel = emulator.getSideEffectLevel(); if (emulator.getExceptions().size() > 0) { node.clearChildren(); node.setExceptions(emulator.getExceptions()); return; node.clearChildren(); return;
@Override public void execute(ExecutionNode node, MethodState mState) { HeapItem lhsItem = mState.readRegister(arg1Register); HeapItem rhsItem; if (hasLiteral) { rhsItem = new HeapItem(narrowLiteral, CommonTypes.INTEGER); } else { rhsItem = mState.readRegister(arg2Register); } Object result = null; if (!lhsItem.isUnknown() && !rhsItem.isUnknown()) { result = getResult(lhsItem.getValue(), rhsItem.getValue()); if (result instanceof Throwable) { Throwable exception = (Throwable) result; node.setException(exception); node.clearChildren(); return; } else { node.clearExceptions(); } } if (null == result) { result = new UnknownValue(); } mState.assignRegister(destRegister, result, mathOperandType.getType()); }