Skip to content

Expose invalid envelope content in receive output - #2084

Open
k-bx wants to merge 5 commits into
AsamK:masterfrom
k-bx:k-bx/2026-07-10-incorrect-range
Open

Expose invalid envelope content in receive output#2084
k-bx wants to merge 5 commits into
AsamK:masterfrom
k-bx:k-bx/2026-07-10-incorrect-range

Conversation

@k-bx

@k-bx k-bx commented Jul 10, 2026

Copy link
Copy Markdown

Problem

Decrypted messages can fail EnvelopeContentValidator, for example when formatting or mention ranges extend beyond the UTF-16 message body.

signal-cli previously logged the validation reason and silently dropped the message. Downstream consumers received no structured event and could not associate the rejection with its sender, device, or envelope timestamps.

Changes

This change:

  • routes invalid-content results through the existing receive exception handler
  • keeps the receive command running successfully
  • includes sender, device, and envelope timestamps in the receive event
  • adds a stable diagnostic code
  • reports UTF-16 body length and offending range coordinates
  • excludes the message body from diagnostic details
  • logs the validator’s synthetic stack trace at debug level

Example:

{
  "exception": {
    "message": "[DataMessage] Body range with out-of-bounds start/length!",
    "type": "InvalidEnvelopeContentException",
    "details": {
      "code": "DATA_MESSAGE_BODY_RANGE_OUT_OF_BOUNDS",
      "bodyLength": 10,
      "invalidBodyRanges": [
        {
          "index": 0,
          "start": 8,
          "length": 4,
          "type": "STYLE_BOLD"
        }
      ]
    }
  },
  "envelope": {
    "sourceUuid": "...",
    "sourceDevice": 2,
    "timestamp": 1234567890
  }
}

The malformed content remains rejected; only its diagnostic metadata is emitted. Existing exception JSON remains unchanged because details is omitted when unavailable.

Testing

  • Added coverage for extracting out-of-bounds body-range diagnostics.
  • Added coverage for structured and ordinary JSON errors.
  • Ran ./gradlew check successfully.

@k-bx k-bx closed this Jul 10, 2026
@k-bx k-bx reopened this Jul 10, 2026
bodyRanges = dataMessage.bodyRanges;
}

final Integer bodyLength = bodyRanges == null ? null : body == null ? 0 : body.length();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

body.length is not sufficient. Messages with more than 2000 chars store the body as an extra attachment.
I'd rather not have the additional length checks here at all. Just notifying the user that the ranges are incorrect should be enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants