Do not crash when receiving invalid message.

This commit is contained in:
Felix Ableitner 2015-01-29 17:46:57 +01:00
parent 5a460c9527
commit 2f08ec0124
2 changed files with 28 additions and 18 deletions

View file

@ -5,6 +5,7 @@ import java.io._
import android.bluetooth.BluetoothSocket import android.bluetooth.BluetoothSocket
import android.util.Log import android.util.Log
import com.nutomic.ensichat.protocol._ import com.nutomic.ensichat.protocol._
import com.nutomic.ensichat.protocol.messages.Message.ReadMessageException
import com.nutomic.ensichat.protocol.messages.{ConnectionInfo, Message, MessageHeader} import com.nutomic.ensichat.protocol.messages.{ConnectionInfo, Message, MessageHeader}
/** /**
@ -54,8 +55,8 @@ class TransferThread(device: Device, socket: BluetoothSocket, Handler: Bluetooth
onReceive(msg, device.Id) onReceive(msg, device.Id)
} }
} catch { } catch {
case e: RuntimeException => case e: ReadMessageException =>
Log.i(Tag, "Received invalid message", e) Log.i(Tag, "Failed to read message", e)
case e: IOException => case e: IOException =>
Log.w(Tag, "Failed to read incoming message", e) Log.w(Tag, "Failed to read incoming message", e)
close() close()

View file

@ -1,6 +1,7 @@
package com.nutomic.ensichat.protocol.messages package com.nutomic.ensichat.protocol.messages
import java.io.InputStream import java.io.InputStream
import java.security.spec.InvalidKeySpecException
object Message { object Message {
@ -16,27 +17,35 @@ object Message {
val Charset = "UTF-8" val Charset = "UTF-8"
class ReadMessageException(throwable: Throwable)
extends RuntimeException(throwable)
def read(stream: InputStream): Message = { def read(stream: InputStream): Message = {
val headerBytes = new Array[Byte](MessageHeader.Length) try {
stream.read(headerBytes, 0, MessageHeader.Length) val headerBytes = new Array[Byte](MessageHeader.Length)
val header = MessageHeader.read(headerBytes) stream.read(headerBytes, 0, MessageHeader.Length)
val header = MessageHeader.read(headerBytes)
val contentLength = (header.Length - MessageHeader.Length).toInt val contentLength = (header.Length - MessageHeader.Length).toInt
val contentBytes = new Array[Byte](contentLength) val contentBytes = new Array[Byte](contentLength)
var numRead = 0 var numRead = 0
do { do {
numRead += stream.read(contentBytes, numRead, contentLength - numRead) numRead += stream.read(contentBytes, numRead, contentLength - numRead)
} while (numRead < contentLength) } while (numRead < contentLength)
val (crypto, remaining) = CryptoData.read(contentBytes) val (crypto, remaining) = CryptoData.read(contentBytes)
val body = val body =
header.MessageType match { header.MessageType match {
case ConnectionInfo.Type => ConnectionInfo.read(remaining) case ConnectionInfo.Type => ConnectionInfo.read(remaining)
case _ => new EncryptedBody(remaining) case _ => new EncryptedBody(remaining)
} }
new Message(header, crypto, body) new Message(header, crypto, body)
} catch {
case e @ (_ : OutOfMemoryError | _ : InvalidKeySpecException) =>
throw new ReadMessageException(e)
}
} }
} }