Skip to content

Commit

Permalink
Added hack for non-null value field in strings (#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
Damtev authored Dec 1, 2023
1 parent 1185f3b commit b5ba5d6
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import org.usvm.api.targets.JcTarget
import org.usvm.collection.array.UArrayIndexLValue
import org.usvm.collection.field.UFieldLValue
import org.usvm.forkblacklists.UForkBlackList
import org.usvm.isStaticHeapRef
import org.usvm.machine.JcApplicationGraph
import org.usvm.machine.JcConcreteMethodCallInst
import org.usvm.machine.JcContext
Expand Down Expand Up @@ -295,6 +296,12 @@ class JcInterpreter(
},
)

// TODO usvm-sbft-merge: hack to prevent NPE for the `value` field in strings
handleStringValueField(
scope,
method,
) { stmt.arguments.first().asExpr(ctx.addressSort) }

scope.doWithState {
addNewMethodCall(stmt, entryPoint)
}
Expand Down Expand Up @@ -322,6 +329,32 @@ class JcInterpreter(
}
}

private fun handleStringValueField(scope: JcStepScope, method: JcMethod, stringRefBlock: () -> UHeapRef) {
with(ctx) {
if (method.isStatic || method.isConstructor) {
return
}

val type = method.enclosingClass.toType()
if (type != stringType) {
return
}

val stringThisRef = stringRefBlock()
if (isStaticHeapRef(stringThisRef)) {
// For string literals we set `value` explicitly
return
}

val stringValueLValue = UFieldLValue(addressSort, stringThisRef, stringValueField.field)
val stringValue = scope.calcOnState { memory.read(stringValueLValue) }

val notNullValueConstraint = mkEq(stringValue, nullRef).not()
scope.assert(notNullValueConstraint)
?: error("Cannot make `java.lang.String#value` not-null for string $stringThisRef")
}
}

private inline fun handleInnerClassMethodCall(
scope: JcStepScope,
enclosingType: JcClassType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,4 +519,12 @@ public String equalsIgnoreCase(String s) {
public String listToString() {
return Arrays.asList("a", "b", "c").toString();
}

public int getSymbolicLength(String s) {
if (s == null) {
return -1;
}

return s.length();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -695,4 +695,14 @@ internal class StringExamplesTest : JavaMethodTestRunner() {
{ _, r -> r == "[a, b, c]" },
)
}

@Test
fun testGetSymbolicLength() {
checkDiscoveredProperties(
StringExamples::getSymbolicLength,
eq(2),
{ _, s, r -> s == null && r == -1 },
{ _, s, r -> s != null && r == s.length },
)
}
}

0 comments on commit b5ba5d6

Please sign in to comment.