mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-07-03 04:25:51 +01:00
Fix body range bounds validation for long text messages.
This commit is contained in:
@@ -28,7 +28,8 @@ final class LogSectionNotifications implements LogSection {
|
||||
.append("New contact alerts : ").append(SignalStore.settings().isNotifyWhenContactJoinsSignal()).append("\n")
|
||||
.append("In-chat sounds : ").append(SignalStore.settings().isMessageNotificationsInChatSoundsEnabled()).append("\n")
|
||||
.append("Repeat alerts : ").append(SignalStore.settings().getMessageNotificationsRepeatAlerts()).append("\n")
|
||||
.append("Notification display : ").append(SignalStore.settings().getMessageNotificationsPrivacy()).append("\n\n");
|
||||
.append("Notification display : ").append(SignalStore.settings().getMessageNotificationsPrivacy()).append("\n")
|
||||
.append("Force websocket : ").append(SignalStore.settings().getForceWebsocketMode()).append("\n\n");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
NotificationManager manager = ServiceUtil.getNotificationManager(context);
|
||||
|
||||
+9
-4
@@ -35,6 +35,7 @@ object EnvelopeContentValidator {
|
||||
private const val MAX_POLL_CHARACTER_LENGTH = 100
|
||||
private const val MIN_POLL_OPTIONS = 2
|
||||
private const val MAX_POLL_OPTIONS = 10
|
||||
private const val LONG_TEXT_CONTENT_TYPE = "text/x-signal-plain"
|
||||
|
||||
fun validate(envelope: Envelope, content: Content, localAci: ACI, ciphertextMessageType: Int): Result {
|
||||
if (envelope.type == Envelope.Type.PLAINTEXT_CONTENT || ciphertextMessageType == CiphertextMessage.PLAINTEXT_CONTENT_TYPE) {
|
||||
@@ -121,7 +122,7 @@ object EnvelopeContentValidator {
|
||||
return Result.Invalid("[DataMessage] Style body range is missing a start or length!")
|
||||
}
|
||||
|
||||
if (dataMessage.bodyRanges.hasInvalidBounds(dataMessage.body)) {
|
||||
if (dataMessage.bodyRanges.hasInvalidBounds(dataMessage.body, allowOutOfBounds = dataMessage.hasLongTextAttachment())) {
|
||||
return Result.Invalid("[DataMessage] Body range with out-of-bounds start/length!")
|
||||
}
|
||||
|
||||
@@ -375,7 +376,7 @@ object EnvelopeContentValidator {
|
||||
return Result.Invalid("[EditMessage] Style body range is missing a start or length!")
|
||||
}
|
||||
|
||||
if (dataMessage.bodyRanges.hasInvalidBounds(dataMessage.body)) {
|
||||
if (dataMessage.bodyRanges.hasInvalidBounds(dataMessage.body, allowOutOfBounds = dataMessage.hasLongTextAttachment())) {
|
||||
return Result.Invalid("[EditMessage] Body range with out-of-bounds start/length!")
|
||||
}
|
||||
|
||||
@@ -390,17 +391,21 @@ object EnvelopeContentValidator {
|
||||
return Result.Valid
|
||||
}
|
||||
|
||||
private fun List<BodyRange>.hasInvalidBounds(body: String?): Boolean {
|
||||
private fun List<BodyRange>.hasInvalidBounds(body: String?, allowOutOfBounds: Boolean = false): 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
|
||||
start < 0 || length < 0 || (!allowOutOfBounds && start + length > bodyLength)
|
||||
}
|
||||
}
|
||||
|
||||
private fun DataMessage.hasLongTextAttachment(): Boolean {
|
||||
return this.attachments.any { it.contentType == LONG_TEXT_CONTENT_TYPE }
|
||||
}
|
||||
|
||||
private fun BodyRange.isStyleRangeMissingOffsets(): Boolean {
|
||||
return this.style != null && (this.start == null || this.length == null)
|
||||
}
|
||||
|
||||
+39
@@ -10,6 +10,7 @@ import org.junit.Test
|
||||
import org.signal.core.models.ServiceId
|
||||
import org.signal.libsignal.protocol.message.CiphertextMessage
|
||||
import org.signal.libsignal.protocol.message.DecryptionErrorMessage
|
||||
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
|
||||
@@ -412,6 +413,44 @@ class EnvelopeContentValidatorTest {
|
||||
assert(result is EnvelopeContentValidator.Result.Invalid)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validate - ensure body range extending past the end of the body is marked valid when a long text attachment is present`() {
|
||||
val content = Content(
|
||||
dataMessage = DataMessage(
|
||||
timestamp = 1234,
|
||||
body = "hello",
|
||||
bodyRanges = listOf(
|
||||
BodyRange(start = 3, length = 10, style = BodyRange.Style.BOLD)
|
||||
),
|
||||
attachments = listOf(
|
||||
AttachmentPointer(cdnKey = "abc", contentType = "text/x-signal-plain")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val result = EnvelopeContentValidator.validate(Envelope(clientTimestamp = 1234), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
|
||||
assert(result is EnvelopeContentValidator.Result.Valid)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validate - ensure body range with negative start is marked invalid even when a long text attachment is present`() {
|
||||
val content = Content(
|
||||
dataMessage = DataMessage(
|
||||
timestamp = 1234,
|
||||
body = "hello",
|
||||
bodyRanges = listOf(
|
||||
BodyRange(start = -1, length = 10, style = BodyRange.Style.BOLD)
|
||||
),
|
||||
attachments = listOf(
|
||||
AttachmentPointer(cdnKey = "abc", contentType = "text/x-signal-plain")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
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(
|
||||
|
||||
Reference in New Issue
Block a user