diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzing/providers/Objects.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzing/providers/Objects.kt index 1322452a01..0b35d166e2 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzing/providers/Objects.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzing/providers/Objects.kt @@ -104,18 +104,6 @@ class ObjectValueProvider( || (type.isInner && !type.isStatic) } - private fun isAccessible(member: Member, packageName: String?): Boolean { - return Modifier.isPublic(member.modifiers) || - (packageName != null && isPackagePrivate(member.modifiers) && member.declaringClass.`package`?.name == packageName) - } - - private fun isPackagePrivate(modifiers: Int): Boolean { - val hasAnyAccessModifier = Modifier.isPrivate(modifiers) - || Modifier.isProtected(modifiers) - || Modifier.isProtected(modifiers) - return !hasAnyAccessModifier - } - private fun findTypesOfNonRecursiveConstructor(type: FuzzedType, packageName: String?): List { return type.classId.allConstructors .filter { isAccessible(it.constructor, packageName) } @@ -186,16 +174,22 @@ internal fun Class<*>.findPublicSetterGetterIfHasPublicGetter(field: Field, pack } } - - internal fun isAccessible(member: Member, packageName: String?): Boolean { + var clazz = member.declaringClass + while (clazz != null) { + if (!isAccessible(clazz, packageName)) return false + clazz = clazz.enclosingClass + } return Modifier.isPublic(member.modifiers) || - (packageName != null && isPackagePrivate(member.modifiers) && member.declaringClass.`package`?.name == packageName) + (packageName != null && isNotPrivateOrProtected(member.modifiers) && member.declaringClass.`package`?.name == packageName) +} + +internal fun isAccessible(clazz: Class<*>, packageName: String?): Boolean { + return Modifier.isPublic(clazz.modifiers) || + (packageName != null && isNotPrivateOrProtected(clazz.modifiers) && clazz.declaringClass.`package`?.name == packageName) } -internal fun isPackagePrivate(modifiers: Int): Boolean { - val hasAnyAccessModifier = Modifier.isPrivate(modifiers) - || Modifier.isProtected(modifiers) - || Modifier.isProtected(modifiers) +private fun isNotPrivateOrProtected(modifiers: Int): Boolean { + val hasAnyAccessModifier = Modifier.isPrivate(modifiers) || Modifier.isProtected(modifiers) return !hasAnyAccessModifier } \ No newline at end of file diff --git a/utbot-fuzzers/src/test/java/org/utbot/fuzzing/samples/AccessibleObjects.java b/utbot-fuzzers/src/test/java/org/utbot/fuzzing/samples/AccessibleObjects.java new file mode 100644 index 0000000000..3c3f92739c --- /dev/null +++ b/utbot-fuzzers/src/test/java/org/utbot/fuzzing/samples/AccessibleObjects.java @@ -0,0 +1,19 @@ +package org.utbot.fuzzing.samples; + +@SuppressWarnings("unused") +public class AccessibleObjects { + + public boolean test(Inn.Node n) { + return n.value * n.value == 36; + } + + private static class Inn { + static class Node { + public int value; + + public Node() { + + } + } + } +} diff --git a/utbot-fuzzers/src/test/kotlin/org/utbot/fuzzing/JavaFuzzingTest.kt b/utbot-fuzzers/src/test/kotlin/org/utbot/fuzzing/JavaFuzzingTest.kt index 65afde2f20..09dc76233e 100644 --- a/utbot-fuzzers/src/test/kotlin/org/utbot/fuzzing/JavaFuzzingTest.kt +++ b/utbot-fuzzers/src/test/kotlin/org/utbot/fuzzing/JavaFuzzingTest.kt @@ -11,6 +11,7 @@ import org.utbot.framework.plugin.api.util.* import org.utbot.fuzzer.FuzzedConcreteValue import org.utbot.fuzzing.samples.DeepNested import org.utbot.fuzzer.FuzzedType +import org.utbot.fuzzing.samples.AccessibleObjects import org.utbot.fuzzing.samples.Stubs import org.utbot.fuzzing.utils.Trie import java.lang.reflect.GenericArrayType @@ -22,23 +23,24 @@ class JavaFuzzingTest { @Test fun `fuzzing doesn't throw an exception when type is unknown`() { - assertDoesNotThrow { - runBlockingWithContext { - runJavaFuzzing( - TestIdentityPreservingIdGenerator, - methodUnderTest = MethodId( - DeepNested.Nested1.Nested2::class.id, - "f", - intClassId, - listOf(intClassId) - ), - constants = emptyList(), - names = emptyList(), - ) { _, _, _ -> - fail("This method is never called") - } + var count = 0 + runBlockingWithContext { + runJavaFuzzing( + TestIdentityPreservingIdGenerator, + methodUnderTest = MethodId( + DeepNested.Nested1.Nested2::class.id, + "f", + intClassId, + listOf(intClassId) + ), + constants = emptyList(), + names = emptyList(), + ) { _, _, _ -> + count += 1 + BaseFeedback(Trie.emptyNode(), Control.STOP) } } + assertEquals(0, count) } @Test @@ -195,6 +197,23 @@ class JavaFuzzingTest { } } + @Test + fun `fuzzing should not generate values of private classes`() { + var exec = 0 + runBlockingWithContext { + runJavaFuzzing( + TestIdentityPreservingIdGenerator, + methodUnderTest = AccessibleObjects::class.java.declaredMethods.first { it.name == "test" }.executableId, + constants = emptyList(), + names = emptyList(), + ) { _, _, _ -> + exec += 1 + BaseFeedback(Trie.emptyNode(), Control.STOP) + } + } + assertEquals(0, exec) { "Fuzzer should not create any values of private classes" } + } + private fun runBlockingWithContext(block: suspend () -> T) : T { return withUtContext(UtContext(this::class.java.classLoader)) { runBlocking {