mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Fix initializer field flow by extracting field finality
This commit is contained in:
@@ -778,19 +778,22 @@ open class KotlinFileExtractor(
|
|||||||
with("field", f) {
|
with("field", f) {
|
||||||
DeclarationStackAdjuster(f).use {
|
DeclarationStackAdjuster(f).use {
|
||||||
declarationStack.push(f)
|
declarationStack.push(f)
|
||||||
return extractField(useField(f), f.name.asString(), f.type, parentId, tw.getLocation(f), f.visibility, f, isExternalDeclaration(f))
|
return extractField(useField(f), f.name.asString(), f.type, parentId, tw.getLocation(f), f.visibility, f, isExternalDeclaration(f), f.isFinal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun extractField(id: Label<out DbField>, name: String, type: IrType, parentId: Label<out DbReftype>, locId: Label<DbLocation>, visibility: DescriptorVisibility, errorElement: IrElement, isExternalDeclaration: Boolean): Label<out DbField> {
|
private fun extractField(id: Label<out DbField>, name: String, type: IrType, parentId: Label<out DbReftype>, locId: Label<DbLocation>, visibility: DescriptorVisibility, errorElement: IrElement, isExternalDeclaration: Boolean, isFinal: Boolean): Label<out DbField> {
|
||||||
val t = useType(type)
|
val t = useType(type)
|
||||||
tw.writeFields(id, name, t.javaResult.id, parentId, id)
|
tw.writeFields(id, name, t.javaResult.id, parentId, id)
|
||||||
tw.writeFieldsKotlinType(id, t.kotlinResult.id)
|
tw.writeFieldsKotlinType(id, t.kotlinResult.id)
|
||||||
tw.writeHasLocation(id, locId)
|
tw.writeHasLocation(id, locId)
|
||||||
|
|
||||||
extractVisibility(errorElement, id, visibility)
|
extractVisibility(errorElement, id, visibility)
|
||||||
|
if (isFinal) {
|
||||||
|
addModifiers(id, "final")
|
||||||
|
}
|
||||||
|
|
||||||
if (!isExternalDeclaration) {
|
if (!isExternalDeclaration) {
|
||||||
val fieldDeclarationId = tw.getFreshIdLabel<DbFielddecl>()
|
val fieldDeclarationId = tw.getFreshIdLabel<DbFielddecl>()
|
||||||
@@ -2949,12 +2952,12 @@ open class KotlinFileExtractor(
|
|||||||
|
|
||||||
// only one of the following can be non-null:
|
// only one of the following can be non-null:
|
||||||
if (dispatchReceiver != null) {
|
if (dispatchReceiver != null) {
|
||||||
extractField(dispatchFieldId!!, "<dispatchReceiver>", receiverType!!, classId, locId, DescriptorVisibilities.PRIVATE, callableReferenceExpr, false)
|
extractField(dispatchFieldId!!, "<dispatchReceiver>", receiverType!!, classId, locId, DescriptorVisibilities.PRIVATE, callableReferenceExpr, isExternalDeclaration = false, isFinal = true)
|
||||||
extractParameterToFieldAssignmentInConstructor("<dispatchReceiver>", dispatchReceiver.type, dispatchFieldId, 0, firstAssignmentStmtIdx)
|
extractParameterToFieldAssignmentInConstructor("<dispatchReceiver>", dispatchReceiver.type, dispatchFieldId, 0, firstAssignmentStmtIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extensionReceiver != null) {
|
if (extensionReceiver != null) {
|
||||||
extractField(extensionFieldId!!, "<extensionReceiver>", receiverType!!, classId, locId, DescriptorVisibilities.PRIVATE, callableReferenceExpr, false)
|
extractField(extensionFieldId!!, "<extensionReceiver>", receiverType!!, classId, locId, DescriptorVisibilities.PRIVATE, callableReferenceExpr, isExternalDeclaration = false, isFinal = true)
|
||||||
extractParameterToFieldAssignmentInConstructor( "<extensionReceiver>", extensionReceiver.type, extensionFieldId, 0 + extensionParameterIndex, firstAssignmentStmtIdx + extensionParameterIndex)
|
extractParameterToFieldAssignmentInConstructor( "<extensionReceiver>", extensionReceiver.type, extensionFieldId, 0 + extensionParameterIndex, firstAssignmentStmtIdx + extensionParameterIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4005,7 +4008,7 @@ open class KotlinFileExtractor(
|
|||||||
|
|
||||||
// add field
|
// add field
|
||||||
val fieldId = tw.getFreshIdLabel<DbField>()
|
val fieldId = tw.getFreshIdLabel<DbField>()
|
||||||
extractField(fieldId, "<fn>", functionType, classId, locId, DescriptorVisibilities.PRIVATE, e, false)
|
extractField(fieldId, "<fn>", functionType, classId, locId, DescriptorVisibilities.PRIVATE, e, isExternalDeclaration = false, isFinal = true)
|
||||||
|
|
||||||
// adjust constructor
|
// adjust constructor
|
||||||
helper.extractParameterToFieldAssignmentInConstructor("<fn>", functionType, fieldId, 0, 1)
|
helper.extractParameterToFieldAssignmentInConstructor("<fn>", functionType, fieldId, 0, 1)
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
isFinalField
|
||||||
|
| test.kt:3:3:3:18 | x |
|
||||||
|
#select
|
||||||
|
| test.kt:3:3:3:18 | this.x | test.kt:6:10:6:10 | getX(...) |
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
class Test {
|
||||||
|
|
||||||
|
val x = "Source"
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
sink(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sink(s: String) { }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import java
|
||||||
|
import semmle.code.java.dataflow.DataFlow
|
||||||
|
|
||||||
|
class Config extends DataFlow::Configuration {
|
||||||
|
|
||||||
|
Config() { this = "dlkjhfgsdjgfhd2" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node n) {
|
||||||
|
n.asExpr().(CompileTimeConstantExpr).getStringValue() = "Source"
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node n) {
|
||||||
|
n.asExpr().(Argument).getCall().getCallee().getName() = "sink"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
query predicate isFinalField(Field f) { exists(FieldDeclaration f2 | f = f2.getAField()) and f.isFinal() }
|
||||||
|
|
||||||
|
from DataFlow::Node source, DataFlow::Node sink
|
||||||
|
where any(Config c).hasFlow(source, sink)
|
||||||
|
select source, sink
|
||||||
Reference in New Issue
Block a user