Do not allow to assign null to a non-null property via reflection
This was already working for accessor-based properties because the assertions were already generated into corresponding accessors, but for fields we must manually check the value against null
This commit is contained in:
@@ -102,8 +102,16 @@ internal sealed class FunctionCaller(
|
||||
|
||||
abstract class FieldSetter(
|
||||
field: ReflectField,
|
||||
private val notNull: Boolean,
|
||||
private val requiresInstance: Boolean
|
||||
) : FieldAccessor(field, if (requiresInstance) 2 else 1) {
|
||||
override fun checkArguments(args: Array<*>) {
|
||||
super.checkArguments(args)
|
||||
if (notNull && args.last() == null) {
|
||||
throw IllegalArgumentException("null is not allowed as a value for this property.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun call(args: Array<*>): Any? {
|
||||
checkArguments(args)
|
||||
return field.set(if (requiresInstance) args.first() else null, args.last())
|
||||
@@ -121,11 +129,11 @@ internal sealed class FunctionCaller(
|
||||
}
|
||||
}
|
||||
|
||||
class StaticFieldSetter(field: ReflectField) : FieldSetter(field, requiresInstance = false)
|
||||
class StaticFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = false)
|
||||
|
||||
class InstanceFieldSetter(field: ReflectField) : FieldSetter(field, requiresInstance = true)
|
||||
class InstanceFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true)
|
||||
|
||||
class PlatformStaticInObjectFieldSetter(field: ReflectField) : FieldSetter(field, requiresInstance = true) {
|
||||
class PlatformStaticInObjectFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true) {
|
||||
override fun checkArguments(args: Array<*>) {
|
||||
super.checkArguments(args)
|
||||
checkObjectInstance(args.firstOrNull())
|
||||
|
||||
@@ -18,6 +18,7 @@ package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Modifier
|
||||
import kotlin.reflect.KMutableProperty
|
||||
@@ -81,16 +82,19 @@ private fun KPropertyImpl.Accessor<*>.computeCallerForAccessor(isGetter: Boolean
|
||||
fun isPlatformStaticProperty() =
|
||||
property.descriptor.annotations.findAnnotation(PLATFORM_STATIC) != null
|
||||
|
||||
fun isNotNullProperty() =
|
||||
!TypeUtils.isNullableType(property.descriptor.type)
|
||||
|
||||
fun computeFieldCaller(field: Field): FunctionCaller.FieldAccessor = when {
|
||||
!Modifier.isStatic(field.modifiers) ->
|
||||
if (isGetter) FunctionCaller.InstanceFieldGetter(field)
|
||||
else FunctionCaller.InstanceFieldSetter(field)
|
||||
else FunctionCaller.InstanceFieldSetter(field, isNotNullProperty())
|
||||
isPlatformStaticProperty() ->
|
||||
if (isGetter) FunctionCaller.PlatformStaticInObjectFieldGetter(field)
|
||||
else FunctionCaller.PlatformStaticInObjectFieldSetter(field)
|
||||
else FunctionCaller.PlatformStaticInObjectFieldSetter(field, isNotNullProperty())
|
||||
else ->
|
||||
if (isGetter) FunctionCaller.StaticFieldGetter(field)
|
||||
else FunctionCaller.StaticFieldSetter(field)
|
||||
else FunctionCaller.StaticFieldSetter(field, isNotNullProperty())
|
||||
}
|
||||
|
||||
val jvmSignature = RuntimeTypeMapper.mapPropertySignature(property.descriptor)
|
||||
|
||||
Reference in New Issue
Block a user