Skip to content

Commit

Permalink
Merge branch 'Guardsquare:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
zlataovce authored Aug 17, 2024
2 parents 7ac7e22 + 5893999 commit 490c254
Show file tree
Hide file tree
Showing 21 changed files with 266 additions and 84 deletions.
10 changes: 5 additions & 5 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ dependencies {

testImplementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}"
testImplementation "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}"
testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.6.2' // for kotest framework
testImplementation 'io.kotest:kotest-assertions-core-jvm:5.6.2' // for kotest core jvm assertions
testImplementation 'io.kotest:kotest-property-jvm:5.6.2' // for kotest property test
testImplementation 'io.kotest:kotest-framework-datatest:5.6.2'
testImplementation 'io.mockk:mockk:1.13.5' // for mocking
testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.7.2' // for kotest framework
testImplementation 'io.kotest:kotest-assertions-core-jvm:5.7.2' // for kotest core jvm assertions
testImplementation 'io.kotest:kotest-property-jvm:5.7.2' // for kotest property test
testImplementation 'io.kotest:kotest-framework-datatest:5.7.2'
testImplementation 'io.mockk:mockk:1.13.12' // for mocking
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.3' // for junit framework
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.3' // for junit framework

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ public class DexFileReader implements BaseDexFileReader {
/** keep clinit method when {@link #SKIP_DEBUG} */
public static final int SKIP_EXCEPTION = 1 << 8;

/** Do not throw an exception if debug info is not valid */
public static final int SKIP_BROKEN_DEBUG_INFO = 1 << 9;

// private static final int REVERSE_ENDIAN_CONSTANT = 0x78563412;

static final int DBG_END_SEQUENCE = 0x00;
Expand Down Expand Up @@ -119,7 +122,7 @@ public class DexFileReader implements BaseDexFileReader {
private static final int TYPE_CALL_SITE_ID_ITEM = 0x0007;
private static final int TYPE_METHOD_HANDLE_ITEM = 0x0008;

private static final boolean SKIP_BROKEN_DEBUG_INFO =
private static final boolean SKIP_BROKEN_DEBUG_INFO_SYSTEM_PROPERTY =
System.getProperty("dex2jar.skip_broken_debug_information") != null;

final ByteBuffer annotationSetRefListIn;
Expand Down Expand Up @@ -1507,6 +1510,8 @@ private void findTryCatch(
}
}
// 处理debug信息
boolean skipBrokenInfo =
SKIP_BROKEN_DEBUG_INFO_SYSTEM_PROPERTY || 0 != (config & SKIP_BROKEN_DEBUG_INFO);
if (debug_info_off != 0 && (0 == (config & SKIP_DEBUG))) {
DexDebugVisitor ddv = dcv.visitDebug();
if (ddv != null) {
Expand All @@ -1515,7 +1520,7 @@ private void findTryCatch(
debug_info_off, registers_size, isStatic, method, labelsMap, ddv, insnsArray.length);
ddv.visitEnd();
} catch (Exception e) {
if (!SKIP_BROKEN_DEBUG_INFO) {
if (!skipBrokenInfo) {
throw e;
}
}
Expand Down
16 changes: 8 additions & 8 deletions base/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ dependencies {
testImplementation "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}"
testFixturesImplementation "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}"
testFixturesImplementation group: "dev.zacsweers.kctfork", name: "core", version: "0.5.0"
testFixturesImplementation 'io.kotest:kotest-runner-junit5-jvm:5.5.4' // for kotest framework
testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.5.4' // for kotest framework
testImplementation 'io.kotest:kotest-assertions-core-jvm:5.5.4' // for kotest core jvm assertions
testFixturesImplementation 'io.kotest:kotest-assertions-core-jvm:5.5.4' // for kotest core jvm assertions

testImplementation 'io.kotest:kotest-property-jvm:5.5.4' // for kotest property test
testImplementation 'io.kotest:kotest-framework-datatest:5.5.4'
testImplementation 'io.mockk:mockk:1.13.3' // for mocking
testFixturesImplementation 'io.kotest:kotest-runner-junit5-jvm:5.7.2' // for kotest framework
testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.7.2' // for kotest framework
testImplementation 'io.kotest:kotest-assertions-core-jvm:5.7.2' // for kotest core jvm assertions
testFixturesImplementation 'io.kotest:kotest-assertions-core-jvm:5.7.2' // for kotest core jvm assertions

testImplementation 'io.kotest:kotest-property-jvm:5.7.2' // for kotest property test
testImplementation 'io.kotest:kotest-framework-datatest:5.7.2'
testImplementation 'io.mockk:mockk:1.13.12' // for mocking
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' // for junit framework
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' // for junit framework

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -513,17 +513,15 @@ private MethodResult createFallbackResult(MethodExecutionInfo methodInfo) {
}
}

// TODO: update to handle array of references the same way as primitive arrays
if (ClassUtil.internalArrayTypeDimensionCount(type) == 1
&& isInternalPrimitiveType(ClassUtil.internalTypeFromArrayType(type))
&& concreteValue != null) {
if (ClassUtil.internalArrayTypeDimensionCount(type) == 1 && concreteValue != null) {
if (concreteValue instanceof Model) {
throw new IllegalStateException(
"Modeled arrays are not supported by ExecutingInvocationUnit");
}
return valueFactory.createArrayReferenceValue(
type,
null, // NB the class is null just because we are filtering for primitive arrays
// This method expects the type of the content of the array
type.substring(1),
referencedClass, // Might be null (for primitive arrays)
valueFactory.createIntegerValue(Array.getLength(concreteValue)),
concreteValue);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package proguard.evaluation.exception;

import proguard.evaluation.value.TypedReferenceValue;

/**
* Represents an exception during partial evaluation when an incomplete class hierarchy was
* encountered.
Expand All @@ -26,5 +28,7 @@ public class IncompleteClassHierarchyException
extends proguard.evaluation.IncompleteClassHierarchyException {
public IncompleteClassHierarchyException(String message) {
super(message);

TypedReferenceValue.INCOMPLETE_CLASS_HIERARCHY = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,17 @@
public class ArrayReferenceValueFactory extends TypedReferenceValueFactory {
// Implementations for ReferenceValue.

@Override
public ReferenceValue createArrayReferenceValue(
String type, Clazz referencedClass, IntegerValue arrayLength) {
return type == null
? REFERENCE_VALUE_NULL
: new ArrayReferenceValue(TypeConstants.ARRAY + type, referencedClass, false, arrayLength);
}

@Override
public ReferenceValue createArrayReferenceValue(
String type, Clazz referencedClass, IntegerValue arrayLength, Object elementValues) {
return createArrayReferenceValue(type, referencedClass, arrayLength);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
/**
* This {@link IdentifiedArrayReferenceValue} represents an identified array reference value with
* its elements.
*
* @author Eric Lafortune
*/
public class DetailedArrayReferenceValue extends IdentifiedArrayReferenceValue {
private static final int MAXIMUM_STORED_ARRAY_LENGTH = 64;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,37 @@
*/
package proguard.evaluation.value;

import proguard.classfile.*;
import proguard.classfile.Clazz;
import proguard.classfile.TypeConstants;
import proguard.classfile.util.ClassUtil;
import proguard.evaluation.value.object.AnalyzedObject;
import proguard.evaluation.value.object.AnalyzedObjectFactory;

/**
* This identified value factory creates array reference values that also represent their elements,
* in as far as possible.
*
* @author Eric Lafortune
*/
public class DetailedArrayValueFactory extends IdentifiedValueFactory {
// Implementations for ReferenceValue.

/** Creates a new DetailedArrayValueFactory, which does not track reference values. */
@Deprecated
public DetailedArrayValueFactory() {
this(new TypedReferenceValueFactory());
}

/**
* Creates a new DetailedArrayValueFactory, which uses the given value factory for non-array
* reference construction.
*/
public DetailedArrayValueFactory(ValueFactory referenceValueFactory) {
// This is quite ugly, but unavoidable without refactoring the value factories hierarchy. Since
// what's currently going on is that DetailedArrayReferenceValue is a ParticularValueFactory
// that overrides all the methods where arrayReferenceValueFactory is used, even if we pass an
// ArrayReferenceValueFactory to super this will never be used.
super(new UnusableArrayValueFactory(), referenceValueFactory);
}

@Override
public ReferenceValue createArrayReferenceValue(
String type, Clazz referencedClass, IntegerValue arrayLength) {
return type == null
Expand All @@ -49,14 +69,17 @@ public ReferenceValue createArrayReferenceValue(
generateReferenceId());
}

@Override
public ReferenceValue createArrayReferenceValue(
String type, Clazz referencedClass, IntegerValue arrayLength, Object elementValues) {

if (type == null) return TypedReferenceValueFactory.REFERENCE_VALUE_NULL;

String arrayType = TypeConstants.ARRAY + type;

if (!arrayLength.isParticular()) {
return new IdentifiedArrayReferenceValue(
type, referencedClass, false, arrayLength, this, generateReferenceId());
arrayType, referencedClass, false, arrayLength, this, generateReferenceId());
}
if (!elementValues.getClass().isArray()
|| elementValues.getClass().getComponentType().isArray()) {
Expand All @@ -66,38 +89,38 @@ public ReferenceValue createArrayReferenceValue(

DetailedArrayReferenceValue detailedArray =
new DetailedArrayReferenceValue(
type, referencedClass, false, arrayLength, this, generateReferenceId());
if (elementValues.getClass().isArray()) {
switch (type.charAt(1)) // 0 is the array char
{
case TypeConstants.BOOLEAN:
storeBooleanArray(detailedArray, (boolean[]) elementValues);
break;
case TypeConstants.BYTE:
storeByteArray(detailedArray, (byte[]) elementValues);
break;
case TypeConstants.CHAR:
storeCharArray(detailedArray, (char[]) elementValues);
break;
case TypeConstants.SHORT:
storeShortArray(detailedArray, (short[]) elementValues);
break;
case TypeConstants.INT:
storeIntArray(detailedArray, (int[]) elementValues);
break;
case TypeConstants.LONG:
storeLongArray(detailedArray, (long[]) elementValues);
break;
case TypeConstants.FLOAT:
storeFloatArray(detailedArray, (float[]) elementValues);
break;
case TypeConstants.DOUBLE:
storeDoubleArray(detailedArray, (double[]) elementValues);
break;
default:
storeObjectArray(detailedArray, (Object[]) elementValues);
}
arrayType, referencedClass, false, arrayLength, this, generateReferenceId());

switch (arrayType.charAt(1)) // 0 is the array char
{
case TypeConstants.BOOLEAN:
storeBooleanArray(detailedArray, (boolean[]) elementValues);
break;
case TypeConstants.BYTE:
storeByteArray(detailedArray, (byte[]) elementValues);
break;
case TypeConstants.CHAR:
storeCharArray(detailedArray, (char[]) elementValues);
break;
case TypeConstants.SHORT:
storeShortArray(detailedArray, (short[]) elementValues);
break;
case TypeConstants.INT:
storeIntArray(detailedArray, (int[]) elementValues);
break;
case TypeConstants.LONG:
storeLongArray(detailedArray, (long[]) elementValues);
break;
case TypeConstants.FLOAT:
storeFloatArray(detailedArray, (float[]) elementValues);
break;
case TypeConstants.DOUBLE:
storeDoubleArray(detailedArray, (double[]) elementValues);
break;
default:
storeObjectArray(detailedArray, (Object[]) elementValues);
}

return detailedArray;
}

Expand Down Expand Up @@ -150,11 +173,48 @@ private void storeDoubleArray(DetailedArrayReferenceValue detailedArray, double[
}
}

private void storeObjectArray(DetailedArrayReferenceValue detailedArray, Object[] elementValues) {
for (int i = 0; i < elementValues.length; i++) {
detailedArray.arrayStore(
createIntegerValue(i),
createReferenceValue(detailedArray.referencedClass, elementValues[i]));
private void storeObjectArray(DetailedArrayReferenceValue detailedArray, Object[] elements) {
for (int i = 0; i < elements.length; i++) {
Object element = elements[i];
Value elementValue;
if (element == null) {
elementValue = createReferenceValueNull();
} else {
Clazz referencedClass = detailedArray.referencedClass;
AnalyzedObject object =
AnalyzedObjectFactory.create(
element,
ClassUtil.internalTypeFromClassName(referencedClass.getName()),
referencedClass);
// Call on referenceValueFactory instead of "this" to avoid the behavior from
// IdentifiedValueFactory (from which DetailedArrayValueFactory should probably not
// inherit).
elementValue =
referenceValueFactory.createReferenceValue(
referencedClass, ClassUtil.isExtendable(referencedClass), false, object);
}
detailedArray.arrayStore(createIntegerValue(i), elementValue);
}
}

/**
* A value factory that should never be used, used as a placeholder for the arrayValueFactory in
* {@link ParticularValueFactory}, since all the methods calling it should be overridden by {@link
* DetailedArrayValueFactory}.
*/
private static class UnusableArrayValueFactory extends ArrayReferenceValueFactory {
@Override
public ReferenceValue createArrayReferenceValue(
String type, Clazz referencedClass, IntegerValue arrayLength) {
throw new IllegalStateException(
"This value factory should never be used, DetailedArrayValueFactory should override all methods calling this");
}

@Override
public ReferenceValue createArrayReferenceValue(
String type, Clazz referencedClass, IntegerValue arrayLength, Object elementValues) {
throw new IllegalStateException(
"This value factory should never be used, DetailedArrayValueFactory should override all methods calling this");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,30 @@ public class IdentifiedValueFactory extends ParticularValueFactory {
private final AtomicInteger doubleID = new AtomicInteger(0);
private static final AtomicInteger referenceIdProvider = new AtomicInteger(0);

/** Creates a new IdentifiedValueFactory which does not keep track of particular references. */
public IdentifiedValueFactory() {
super();
}

/**
* Creates a new IdentifiedValueFactory, which uses the given valuefactory for both array and
* non-array reference construction.
*/
public IdentifiedValueFactory(ValueFactory referenceValueFactory) {
super(referenceValueFactory);
}

/**
* Creates a new IdentifiedValueFactory.
*
* @param arrayReferenceValueFactory the valuefactory to delegate new array references to.
* @param referenceValueFactory the valuefactory to delegate new references to.
*/
public IdentifiedValueFactory(
ValueFactory arrayReferenceValueFactory, ValueFactory referenceValueFactory) {
super(arrayReferenceValueFactory, referenceValueFactory);
}

// Implementations for BasicValueFactory.

public IntegerValue createIntegerValue() {
Expand Down Expand Up @@ -121,9 +145,7 @@ public ReferenceValue createReferenceValueForId(
boolean mayBeNull,
Object id,
Object value) {
return type == null
? TypedReferenceValueFactory.REFERENCE_VALUE_NULL
: new IdentifiedReferenceValue(type, referencedClass, mayBeExtension, mayBeNull, this, id);
return this.createReferenceValueForId(type, referencedClass, mayBeExtension, mayBeNull, id);
}

public ReferenceValue createArrayReferenceValue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
* with an associated value. E.g., a String with the value "HelloWorld".
*/
public class ParticularReferenceValue extends IdentifiedReferenceValue {
public static boolean ARRAY_EXCEPTIONS =
System.getProperty("proguard.particularvalue.arrayexceptions") != null;

// The actual value of the object.
private final AnalyzedObject objectValue;
Expand All @@ -51,6 +53,12 @@ public ParticularReferenceValue(
value.getType(),
"ParticularReferenceValue should not be created with a 'NullObject', a 'TypedReferenceValue' with null type is expected in that case");

if (ARRAY_EXCEPTIONS
&& proguard.classfile.util.ClassUtil.isInternalArrayType(value.getType())) {
throw new IllegalStateException(
"ParticularReferenceValue should not be used for arrays use DetailedArrayReferenceValue instead");
}

this.objectValue = value;
}

Expand Down
Loading

0 comments on commit 490c254

Please sign in to comment.