Merge pull request #1157 from akka/wip-2800-no-null-msg-master-patriknw

Add fail fast checks to prevent null message, see #2800
This commit is contained in:
Patrik Nordwall 2013-02-21 12:41:17 -08:00
commit 617bb979c1
7 changed files with 21 additions and 10 deletions

View file

@ -452,6 +452,7 @@ private[akka] class EmptyLocalActorRef(override val provider: ActorRefProvider,
}
override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = message match {
case null throw new InvalidMessageException("Message is null")
case d: DeadLetter
specialHandle(d.message) // do NOT form endless loops, since deadLetters will resend!
case _ if !specialHandle(message)
@ -480,6 +481,7 @@ private[akka] class DeadLetterActorRef(_provider: ActorRefProvider,
_eventStream: EventStream) extends EmptyLocalActorRef(_provider, _path, _eventStream) {
override def !(message: Any)(implicit sender: ActorRef = this): Unit = message match {
case null throw new InvalidMessageException("Message is null")
case d: DeadLetter if (!specialHandle(d.message)) eventStream.publish(d)
case _ if (!specialHandle(message))
eventStream.publish(DeadLetter(message, if (sender eq Actor.noSender) provider.deadLetters else sender, this))

View file

@ -386,6 +386,7 @@ class LocalActorRefProvider private[akka] (
override def isTerminated: Boolean = stopped.isOn
override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = stopped.ifOff(message match {
case null throw new InvalidMessageException("Message is null")
case Failed(ex, _) if sender ne null { causeOfTermination = Some(ex); sender.asInstanceOf[InternalActorRef].stop() }
case NullMessage // do nothing
case _ log.error(this + " received unexpected message [" + message + "]")

View file

@ -91,7 +91,6 @@ private[akka] trait Dispatch { this: ActorCell ⇒
def sendMessage(msg: Envelope): Unit =
try {
val m = msg.message.asInstanceOf[AnyRef]
if (m eq null) throw new InvalidMessageException("Message is null")
if (system.settings.SerializeAllMessages && !m.isInstanceOf[NoSerializationVerificationNeeded]) {
val s = SerializationExtension(system)
s.deserialize(s.serialize(m).get, m.getClass).get

View file

@ -20,8 +20,10 @@ import scala.util.control.NonFatal
final case class Envelope private (val message: Any, val sender: ActorRef)
object Envelope {
def apply(message: Any, sender: ActorRef, system: ActorSystem): Envelope =
def apply(message: Any, sender: ActorRef, system: ActorSystem): Envelope = {
if (message == null) throw new InvalidMessageException("Message is null")
new Envelope(message, if (sender ne Actor.noSender) sender else system.deadLetters)
}
}
/**

View file

@ -720,7 +720,10 @@ object Logging {
val path: ActorPath = new RootActorPath(Address("akka", "all-systems"), "/StandardOutLogger")
def provider: ActorRefProvider = throw new UnsupportedOperationException("StandardOutLogger does not provide")
override val toString = "StandardOutLogger"
override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = print(message)
override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = {
if (message == null) throw new InvalidMessageException("Message is null")
print(message)
}
}
val StandardOutLogger = new StandardOutLogger

View file

@ -193,12 +193,14 @@ private[akka] final class PromiseActorRef private (val provider: ActorRefProvide
override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = state match {
case Stopped | _: StoppedWithPath provider.deadLetters ! message
case _ if (!(result.tryComplete(
message match {
case Status.Success(r) Success(r)
case Status.Failure(f) Failure(f)
case other Success(other)
}))) provider.deadLetters ! message
case _
if (message == null) throw new InvalidMessageException("Message is null")
if (!(result.tryComplete(
message match {
case Status.Success(r) Success(r)
case Status.Failure(f) Failure(f)
case other Success(other)
}))) provider.deadLetters ! message
}
override def sendSystemMessage(message: SystemMessage): Unit = message match {

View file

@ -355,8 +355,10 @@ private[akka] class RemoteActorRef private[akka] (
def sendSystemMessage(message: SystemMessage): Unit = try remote.send(message, None, this) catch handleException
override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit =
override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = {
if (message == null) throw new InvalidMessageException("Message is null")
try remote.send(message, Option(sender), this) catch handleException
}
def start(): Unit = if (props.isDefined && deploy.isDefined) provider.useActorOnNode(path, props.get, deploy.get, getParent)