Allow missing recipient for drafts
This commit is contained in:
parent
fab1c06135
commit
681ea148db
@ -87,10 +87,10 @@ class Plaintext private constructor(
|
||||
if (to == null) {
|
||||
return
|
||||
}
|
||||
if (this.to != null) {
|
||||
if (this.to!!.version != 0L)
|
||||
this.to?.let {
|
||||
if (it.version != 0L)
|
||||
throw IllegalStateException("Correct address already set")
|
||||
if (!Arrays.equals(this.to!!.ripe, to.ripe)) {
|
||||
if (!Arrays.equals(it.ripe, to.ripe)) {
|
||||
throw IllegalArgumentException("RIPEs don't match")
|
||||
}
|
||||
}
|
||||
@ -187,7 +187,8 @@ class Plaintext private constructor(
|
||||
Factory.getObjectMessage(
|
||||
3,
|
||||
ByteArrayInputStream(ackMessage),
|
||||
ackMessage.size)
|
||||
ackMessage.size
|
||||
)
|
||||
} else null
|
||||
},
|
||||
conversationId = conversationId,
|
||||
@ -243,7 +244,8 @@ class Plaintext private constructor(
|
||||
Factory.getObjectMessage(
|
||||
3,
|
||||
ByteArrayInputStream(ackMsg),
|
||||
ackMsg.size)
|
||||
ackMsg.size
|
||||
)
|
||||
} else {
|
||||
Factory.createAck(builder.from!!, builder.ackData, builder.ttl)
|
||||
}
|
||||
@ -462,7 +464,12 @@ class Plaintext private constructor(
|
||||
}
|
||||
}.invoke()
|
||||
if (item.type == MSG) {
|
||||
out.write(item.to?.ripe ?: throw IllegalStateException("No recipient set for message"))
|
||||
// A draft without recipient is allowed, therefore this workaround.
|
||||
item.to?.let { out.write(it.ripe) } ?: if (item.status == Status.DRAFT) {
|
||||
out.write(ByteArray(20))
|
||||
} else {
|
||||
throw IllegalStateException("No recipient set for message")
|
||||
}
|
||||
}
|
||||
Encode.varInt(item.encodingCode, out)
|
||||
Encode.varInt(item.message.size, out)
|
||||
@ -508,7 +515,12 @@ class Plaintext private constructor(
|
||||
}
|
||||
}
|
||||
if (item.type == MSG) {
|
||||
buffer.put(item.to!!.ripe)
|
||||
// A draft without recipient is allowed, therefore this workaround.
|
||||
item.to?.let { buffer.put(it.ripe) } ?: if (item.status == Status.DRAFT) {
|
||||
buffer.put(ByteArray(20))
|
||||
} else {
|
||||
throw IllegalStateException("No recipient set for message")
|
||||
}
|
||||
}
|
||||
Encode.varInt(item.encodingCode, buffer)
|
||||
Encode.varBytes(item.message, buffer)
|
||||
@ -727,15 +739,17 @@ class Plaintext private constructor(
|
||||
|
||||
internal fun prepare(): Builder {
|
||||
if (from == null) {
|
||||
from = BitmessageAddress(Factory.createPubkey(
|
||||
addressVersion,
|
||||
stream,
|
||||
publicSigningKey!!,
|
||||
publicEncryptionKey!!,
|
||||
nonceTrialsPerByte,
|
||||
extraBytes,
|
||||
behaviorBitfield
|
||||
))
|
||||
from = BitmessageAddress(
|
||||
Factory.createPubkey(
|
||||
addressVersion,
|
||||
stream,
|
||||
publicSigningKey!!,
|
||||
publicEncryptionKey!!,
|
||||
nonceTrialsPerByte,
|
||||
extraBytes,
|
||||
behaviorBitfield
|
||||
)
|
||||
)
|
||||
}
|
||||
if (to == null && type != Type.BROADCAST && destinationRipe != null) {
|
||||
to = BitmessageAddress(0, 0, destinationRipe!!)
|
||||
@ -743,7 +757,7 @@ class Plaintext private constructor(
|
||||
if (preventAck) {
|
||||
ackData = null
|
||||
ackMessage = null
|
||||
} else if (type == MSG && ackMessage == null && ackData == null) {
|
||||
} else if (type == MSG && ackMessage == null && ackData == null && to?.has(Feature.DOES_ACK) == true) {
|
||||
ackData = cryptography().randomBytes(Msg.ACK_LENGTH)
|
||||
}
|
||||
if (ttl <= 0) {
|
||||
@ -784,7 +798,9 @@ class Plaintext private constructor(
|
||||
.publicEncryptionKey(Decode.bytes(input, 64))
|
||||
.nonceTrialsPerByte(if (version >= 3) Decode.varInt(input) else 0)
|
||||
.extraBytes(if (version >= 3) Decode.varInt(input) else 0)
|
||||
.destinationRipe(if (type == MSG) Decode.bytes(input, 20) else null)
|
||||
.destinationRipe(if (type == MSG) Decode.bytes(input, 20).let {
|
||||
if (it.any { x -> x != 0.toByte() }) it else null
|
||||
} else null)
|
||||
.encoding(Decode.varInt(input))
|
||||
.message(Decode.varBytes(input))
|
||||
.ackMessage(if (type == MSG) Decode.varBytes(input) else null)
|
||||
|
@ -123,6 +123,31 @@ class SerializationTest : TestBase() {
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure plaintext without recipient can be serialized (needed for saving drafts)`() {
|
||||
val expected = Plaintext.Builder(MSG)
|
||||
.from(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"))
|
||||
.message(Message.Builder()
|
||||
.subject("Subject")
|
||||
.body("Message")
|
||||
.build())
|
||||
.signature(ByteArray(0))
|
||||
.status(Plaintext.Status.DRAFT)
|
||||
.build()
|
||||
val out = ByteArrayOutputStream()
|
||||
expected.writer().write(out)
|
||||
val input = ByteArrayInputStream(out.toByteArray())
|
||||
val actual = Plaintext.read(MSG, input)
|
||||
actual.status = Plaintext.Status.DRAFT // status isn't serialized, that's OK
|
||||
|
||||
// Received is automatically set on deserialization, so we'll need to set it to null
|
||||
val received = Plaintext::class.java.getDeclaredField("received")
|
||||
received.isAccessible = true
|
||||
received.set(actual, null)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure plaintext with ack message is serialized and deserialized correctly`() {
|
||||
val expected = Plaintext.Builder(MSG)
|
||||
|
Loading…
Reference in New Issue
Block a user