Add kotlin throwables to whitelist (#1424)

This commit is contained in:
Andrzej Cichocki 2017-09-06 12:58:06 +01:00 committed by GitHub
parent fe17d26bb0
commit b2051952d2
4 changed files with 78 additions and 3 deletions

1
.gitignore vendored
View File

@ -16,6 +16,7 @@ local.properties
**/build/*
lib/dokka.jar
lib/quasar.jar
**/logs/*

View File

@ -0,0 +1,64 @@
package net.corda.client.rpc
import com.esotericsoftware.kryo.KryoException
import net.corda.core.concurrent.CordaFuture
import net.corda.core.internal.concurrent.openFuture
import net.corda.core.messaging.*
import net.corda.core.utilities.getOrThrow
import net.corda.testing.rpcDriver
import net.corda.testing.startRpcClient
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test
class RPCFailureTests {
class Unserializable
interface Ops : RPCOps {
fun getUnserializable(): Unserializable
fun getUnserializableAsync(): CordaFuture<Unserializable>
fun kotlinNPE()
fun kotlinNPEAsync(): CordaFuture<Unit>
}
class OpsImpl : Ops {
override val protocolVersion = 1
override fun getUnserializable() = Unserializable()
override fun getUnserializableAsync(): CordaFuture<Unserializable> {
return openFuture<Unserializable>().apply { capture { getUnserializable() } }
}
override fun kotlinNPE() {
(null as Any?)!!.hashCode()
}
override fun kotlinNPEAsync(): CordaFuture<Unit> {
return openFuture<Unit>().apply { capture { kotlinNPE() } }
}
}
private fun rpc(proc: (Ops) -> Any?): Unit = rpcDriver {
val server = startRpcServer(ops = OpsImpl()).getOrThrow()
proc(startRpcClient<Ops>(server.broker.hostAndPort!!).getOrThrow())
}
@Test
fun `kotlin NPE`() = rpc {
assertThatThrownBy { it.kotlinNPE() }.isInstanceOf(KotlinNullPointerException::class.java)
}
@Test
fun `kotlin NPE async`() = rpc {
val future = it.kotlinNPEAsync()
assertThatThrownBy { future.getOrThrow() }.isInstanceOf(KotlinNullPointerException::class.java)
}
@Test
fun `unserializable`() = rpc {
assertThatThrownBy { it.getUnserializable() }.isInstanceOf(KryoException::class.java)
}
@Test
fun `unserializable async`() = rpc {
val future = it.getUnserializableAsync()
assertThatThrownBy { future.getOrThrow() }.isInstanceOf(KryoException::class.java)
}
}

View File

@ -170,7 +170,7 @@ object RPCApi {
override fun writeToClientMessage(context: SerializationContext, message: ClientMessage) {
message.putIntProperty(TAG_FIELD_NAME, Tag.RPC_REPLY.ordinal)
message.putLongProperty(RPC_ID_FIELD_NAME, id.toLong)
message.bodyBuffer.writeBytes(result.serialize(context = context).bytes)
message.bodyBuffer.writeBytes(result.safeSerialize(context) { Try.Failure(it) }.bytes)
}
}
@ -181,11 +181,17 @@ object RPCApi {
override fun writeToClientMessage(context: SerializationContext, message: ClientMessage) {
message.putIntProperty(TAG_FIELD_NAME, Tag.OBSERVATION.ordinal)
message.putLongProperty(OBSERVABLE_ID_FIELD_NAME, id.toLong)
message.bodyBuffer.writeBytes(content.serialize(context = context).bytes)
message.bodyBuffer.writeBytes(content.safeSerialize(context) { Notification.createOnError<Void?>(it) }.bytes)
}
}
companion object {
private fun Any.safeSerialize(context: SerializationContext, wrap: (Throwable) -> Any) = try {
serialize(context = context)
} catch (t: Throwable) {
wrap(t).serialize(context = context)
}
fun fromClientMessage(context: SerializationContext, message: ClientMessage): ServerToClient {
val tag = Tag.values()[message.getIntProperty(TAG_FIELD_NAME)]
return when (tag) {

View File

@ -139,7 +139,11 @@ object EmptyWhitelist : ClassWhitelist {
}
class BuiltInExceptionsWhitelist : ClassWhitelist {
override fun hasListed(type: Class<*>): Boolean = Throwable::class.java.isAssignableFrom(type) && type.`package`.name.startsWith("java.")
companion object {
private val packageName = "^(?:java|kotlin)(?:[.]|$)".toRegex()
}
override fun hasListed(type: Class<*>) = Throwable::class.java.isAssignableFrom(type) && packageName.containsMatchIn(type.`package`.name)
}
object AllWhitelist : ClassWhitelist {