Improve body range validations.
This commit is contained in:
parent
26b1d3a0f8
commit
ccfbb27695
@ -10,6 +10,7 @@ import org.signal.libsignal.zkgroup.InvalidInputException
|
||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey
|
||||
import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialPresentation
|
||||
import org.whispersystems.signalservice.internal.push.AttachmentPointer
|
||||
import org.whispersystems.signalservice.internal.push.BodyRange
|
||||
import org.whispersystems.signalservice.internal.push.Content
|
||||
import org.whispersystems.signalservice.internal.push.DataMessage
|
||||
import org.whispersystems.signalservice.internal.push.EditMessage
|
||||
@ -96,6 +97,10 @@ object EnvelopeContentValidator {
|
||||
return Result.Invalid("[DataMessage] Invalid ACI on quote body range!")
|
||||
}
|
||||
|
||||
if (dataMessage.quote != null && dataMessage.quote.bodyRanges.hasInvalidBounds(dataMessage.quote.text)) {
|
||||
return Result.Invalid("[DataMessage] Quote body range with out-of-bounds start/length!")
|
||||
}
|
||||
|
||||
if (dataMessage.contact.any { it.avatar != null && it.avatar.avatar.isPresentAndInvalid() }) {
|
||||
return Result.Invalid("[DataMessage] Invalid AttachmentPointer on DataMessage.contactList.avatar!")
|
||||
}
|
||||
@ -108,6 +113,10 @@ object EnvelopeContentValidator {
|
||||
return Result.Invalid("[DataMessage] Invalid ACI on body range!")
|
||||
}
|
||||
|
||||
if (dataMessage.bodyRanges.hasInvalidBounds(dataMessage.body)) {
|
||||
return Result.Invalid("[DataMessage] Body range with out-of-bounds start/length!")
|
||||
}
|
||||
|
||||
if (dataMessage.sticker != null && dataMessage.sticker.data_.isNullOrInvalid()) {
|
||||
return Result.Invalid("[DataMessage] Invalid AttachmentPointer on DataMessage.sticker!")
|
||||
}
|
||||
@ -354,6 +363,10 @@ object EnvelopeContentValidator {
|
||||
return Result.Invalid("[EditMessage] Invalid UUID on body range!")
|
||||
}
|
||||
|
||||
if (dataMessage.bodyRanges.hasInvalidBounds(dataMessage.body)) {
|
||||
return Result.Invalid("[EditMessage] Body range with out-of-bounds start/length!")
|
||||
}
|
||||
|
||||
if (dataMessage.attachments.any { it.isNullOrInvalid() }) {
|
||||
return Result.Invalid("[EditMessage] Invalid attachments!")
|
||||
}
|
||||
@ -365,6 +378,17 @@ object EnvelopeContentValidator {
|
||||
return Result.Valid
|
||||
}
|
||||
|
||||
private fun List<BodyRange>.hasInvalidBounds(body: String?): Boolean {
|
||||
val bodyLength: Long = (body?.length ?: 0).toLong()
|
||||
|
||||
return this.any { range ->
|
||||
val start: Long = (range.start ?: 0).toLong()
|
||||
val length: Long = (range.length ?: 0).toLong()
|
||||
|
||||
start < 0 || length < 0 || start + length > bodyLength
|
||||
}
|
||||
}
|
||||
|
||||
private fun AttachmentPointer?.isNullOrInvalid(): Boolean {
|
||||
return this == null || (this.cdnId == null && this.cdnKey == null)
|
||||
}
|
||||
|
||||
@ -328,6 +328,7 @@ class EnvelopeContentValidatorTest {
|
||||
quote = DataMessage.Quote(
|
||||
id = 1000,
|
||||
authorAci = OTHER_ACI.toString(),
|
||||
text = "hello",
|
||||
bodyRanges = listOf(
|
||||
BodyRange(start = 0, length = 1, mentionAci = OTHER_ACI.toString())
|
||||
)
|
||||
@ -339,6 +340,94 @@ class EnvelopeContentValidatorTest {
|
||||
assert(result is EnvelopeContentValidator.Result.Valid)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validate - ensure quote body range whose start plus length overflows is marked invalid`() {
|
||||
val content = Content(
|
||||
dataMessage = DataMessage(
|
||||
timestamp = 1234,
|
||||
quote = DataMessage.Quote(
|
||||
id = 1000,
|
||||
authorAci = OTHER_ACI.toString(),
|
||||
text = "hello",
|
||||
bodyRanges = listOf(
|
||||
BodyRange(start = 1, length = Int.MAX_VALUE, mentionAci = OTHER_ACI.toString())
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val result = EnvelopeContentValidator.validate(Envelope(clientTimestamp = 1234), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
|
||||
assert(result is EnvelopeContentValidator.Result.Invalid)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validate - ensure quote body range extending past the end of the text is marked invalid`() {
|
||||
val content = Content(
|
||||
dataMessage = DataMessage(
|
||||
timestamp = 1234,
|
||||
quote = DataMessage.Quote(
|
||||
id = 1000,
|
||||
authorAci = OTHER_ACI.toString(),
|
||||
text = "hello",
|
||||
bodyRanges = listOf(
|
||||
BodyRange(start = 3, length = 10, style = BodyRange.Style.BOLD)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val result = EnvelopeContentValidator.validate(Envelope(clientTimestamp = 1234), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
|
||||
assert(result is EnvelopeContentValidator.Result.Invalid)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validate - ensure body range whose start plus length overflows is marked invalid`() {
|
||||
val content = Content(
|
||||
dataMessage = DataMessage(
|
||||
timestamp = 1234,
|
||||
body = "hello",
|
||||
bodyRanges = listOf(
|
||||
BodyRange(start = 1, length = Int.MAX_VALUE, mentionAci = OTHER_ACI.toString())
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val result = EnvelopeContentValidator.validate(Envelope(clientTimestamp = 1234), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
|
||||
assert(result is EnvelopeContentValidator.Result.Invalid)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validate - ensure body range extending past the end of the body is marked invalid`() {
|
||||
val content = Content(
|
||||
dataMessage = DataMessage(
|
||||
timestamp = 1234,
|
||||
body = "hello",
|
||||
bodyRanges = listOf(
|
||||
BodyRange(start = 3, length = 10, style = BodyRange.Style.BOLD)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val result = EnvelopeContentValidator.validate(Envelope(clientTimestamp = 1234), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
|
||||
assert(result is EnvelopeContentValidator.Result.Invalid)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validate - ensure body range that exactly covers the body is marked valid`() {
|
||||
val content = Content(
|
||||
dataMessage = DataMessage(
|
||||
timestamp = 1234,
|
||||
body = "hello",
|
||||
bodyRanges = listOf(
|
||||
BodyRange(start = 0, length = 5, style = BodyRange.Style.BOLD)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val result = EnvelopeContentValidator.validate(Envelope(clientTimestamp = 1234), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
|
||||
assert(result is EnvelopeContentValidator.Result.Valid)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validate - ensure sync blocked with invalid string aci and empty binary list is marked invalid`() {
|
||||
val envelope = Envelope(sourceServiceId = SELF_ACI.toString())
|
||||
|
||||
Loading…
Reference in New Issue
Block a user