[CORDA-2330] Turn on lenient mode in rpc serialization context. (#4409)

This commit is contained in:
Florian Friemel 2018-12-17 15:33:25 +00:00 committed by GitHub
parent 20e5bbf56f
commit 58b0cdaef7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 1 deletions

View File

@ -21,5 +21,6 @@ val AMQP_RPC_CLIENT_CONTEXT = SerializationContextImpl(
emptyMap(),
true,
SerializationContext.UseCase.RPCClient,
null
null,
lenientCarpenterEnabled = true
)

View File

@ -0,0 +1,63 @@
package net.corda.serialization.internal.amqp
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState
import net.corda.core.serialization.SerializationContext
import net.corda.core.serialization.SerializedBytes
import net.corda.serialization.internal.AllWhitelist
import net.corda.serialization.internal.SerializationContextImpl
import net.corda.serialization.internal.amqp.testutils.*
import net.corda.serialization.internal.carpenter.ClassCarpenterImpl
import org.junit.Test
data class TestState(override val participants: List<AbstractParty>): QueryableState {
override fun generateMappedObject(schema: MappedSchema): PersistentState {
throw NotImplementedError()
}
override fun supportedSchemas(): Iterable<MappedSchema> {
throw NotImplementedError()
}
}
/**
* A class loader that excludes [TestState].
*/
class ClassLoaderWithoutTestState(classLoader: ClassLoader): ClassLoader(classLoader) {
override fun loadClass(name: String?, resolve: Boolean): Class<*> {
if(name != null && name.contains("TestState")) {
throw ClassNotFoundException()
}
return super.loadClass(name, resolve)
}
}
class DeserializeQueryableStateTest {
/**
* Set `lenient` to false to reproduce CORDA-2330
* https://r3-cev.atlassian.net/browse/CORDA-2330
*/
@Test
fun `should deserialize subclass of QueryableState that is not present in the class loader`() {
val lenient = true
val instance = TestState(listOf())
val serialized = TestSerializationOutput(false, testDefaultFactory()).serialize(instance)
val sf = SerializerFactoryBuilder.build(AllWhitelist, ClassCarpenterImpl(AllWhitelist, ClassLoaderWithoutTestState(ClassLoader.getSystemClassLoader()), lenient))
val context = SerializationContextImpl(
preferredSerializationVersion = amqpMagic,
deserializationClassLoader = ClassLoaderWithoutTestState(ClassLoader.getSystemClassLoader()),
whitelist = AllWhitelist,
properties = serializationProperties,
objectReferencesEnabled = false,
useCase = SerializationContext.UseCase.Testing,
encoding = null)
val bytes = SerializedBytes<QueryableState>(serialized.bytes)
// will throw when lenient is false
DeserializationInput(sf).deserialize(bytes, context)
}
}