Skip to content

Fuzzer generates values even when class is private #1635 #1638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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<ConstructorId> {
return type.classId.allConstructors
.filter { isAccessible(it.constructor, packageName) }
Expand Down Expand Up @@ -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
}
Original file line number Diff line number Diff line change
@@ -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() {

}
}
}
}
49 changes: 34 additions & 15 deletions utbot-fuzzers/src/test/kotlin/org/utbot/fuzzing/JavaFuzzingTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 <T> runBlockingWithContext(block: suspend () -> T) : T {
return withUtContext(UtContext(this::class.java.classLoader)) {
runBlocking {
Expand Down