Closed Bug 1997519 Opened 8 months ago Closed 7 months ago

Behavior change in WebExtension API (using addon, forwarded inline images not shown)

Categories

(Thunderbird :: Add-Ons: Extensions API, defect)

Thunderbird 144
defect

Tracking

(thunderbird_esr140 unaffected, thunderbird148 fixed)

RESOLVED FIXED
148 Branch
Tracking Status
thunderbird_esr140 --- unaffected
thunderbird148 --- fixed

People

(Reporter: soloparalapublicidad, Assigned: john)

References

Details

Attachments

(1 file, 3 obsolete files)

Steps to reproduce:

I'm a user (not the developer) of an add-on called ReplyWithHeader, which modifies email headers when forwarding or replying. I'm also using an IMAP account via DavMail. Everything worked fine up to version 140.4.0esr, but after updating —starting with v143 and continuing with the latest stable version, v144.0.1— inline images no longer appear. I'm using Thunderbird 64 bits in Windows 10.

Steps to reproduce:

Open an email that contains an inline image. It will include a block similar to the following:

--010_AM9PR04MB81303AAFC8947868B558B8AA97F8AAM9PR04MB8130eurp
Content-Type: image/png; name="image001.png"
Content-Description: image001.png
Content-Disposition: inline; filename="image001.png"; size=14939;
creation-date="Thu, 30 Oct 2025 14:13:10 GMT";
modification-date="Fri, 31 Oct 2025 07:24:18 GMT"
Content-ID: <image001.png@01DC49AE.C3862D80>
Content-Transfer-Encoding: base64

<base64_content_of_the_picture>

In the email body, the image is referenced using an <img> tag with src="cid:image001.png@01DC49AE.C3862D80".

Actual results:

When you forward the email, the image disappears and is replaced by a placeholder pointing to an URL like this: imap://XXXXXXX%40DOMAIN@localhost:PORT/fetch%3EUID%3E/INBOX%3E308685?part=1.1.2&filename=image001.png

The error console shows the following message (in Spanish):
Error de seguridad: el contenido en moz-nullprincipal:{25f36377-6b2d-4d0e-a1d5-c105a98dce73} no puede cargar o enlazar con imap://XXXXXXX%40DOMAIN@localhost:PORT/fetch%3EUID%3E/INBOX%3E308685?part=1.1.2&filename=image001.png.

Which likely translates to:
Security error: the content at moz-nullprincipal:{25f36377-6b2d-4d0e-a1d5-c105a98dce73} cannot load or link to imap://XXXXXXX%40DOMAIN@localhost:PORT/fetch%3EUID%3E/INBOX%3E308685?part=1.1.2&filename=image001.png.

Expected results:

The expected behavior is that, even in the compose windows (previous to sending the email), the inline images should appear.

If you disable this add-on (or others with similar functionality, so it seems related to header editing in general), everything works fine: Thunderbird correctly forwards inline images. This suggests the issue lies within the add-on itself.

I read a developer's response suggesting that something in the WebExtension API, possibly the setComposeDetails function, may have changed since v140 and that they can't fix it. However, I’ve checked the release notes and haven’t found any mention of such changes.

I'm posting this to help the add-on developers help me ;). Has the API actually changed in these versions? Could a new permission be required, or has something in the API these add-ons rely on been deprecated? Is it possible there's a bug in Thunderbird's API?

Thanks for the report. I assume the filed issue is: https://github.com/jeevatkm/ReplyWithHeader-Thunderbird/issues/197

Thanks for making us aware of this issue, it sure is interesting. It seems to be a timing issue, and modifications to (unrelated?) core code changed the point in time when add-ons receive the content of the newly opened composer for the first time. The composer initially loads the raw content of the message and later replaces imap:// sources of inline images to data:// URLs. Without this, Thunderbird would also not display these inline images.

For unknown reasons, add-ons have received the "fixed" body in the past, but now get the original body, when they listen for newly opened compose windows. A quick dirty fix would be to wait a few ms before grabbing the content. A delay of 250ms before calling

let composeDetails = await messenger.compose.getComposeDetails(tab.id);

(/modules/compose.js:27)

fixed it for me. This is of course not more than a quick hack. We will investigate how to resolve this.

The WebExtension API currently waits for the compose-editor-ready event to detect
when a compose window is ready. However, certain modifications are still applied
after that event, most notably image conversions from mailnews URLs to data:
URLs.

Due to other code changes, the event is now seen too early by WebExtensions. This
patch aims to correctly wait until after the image conversion has finished.

The current code waits for an error event if an image could not be loaded, in order
to convert it to a data: URL. These error events are fired after the load event,
and there is no mechanism besides "waiting a bit" to ensure all images have been
converted.

The background image is already converted manually. This patch moves the conversion
process of the other images out of the error event and handles them alongside the
background image. We still get CSP errors for the original imap:// URLs, but we
are now able to set a well-defined status once the content of the editor is fully
loaded.

This patch also moves all WebExtension APIs that act on the compose window to use
the new compose-editor-content-ready event.

Assignee: nobody → john
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true

(In reply to John Bieling from comment #1)

Thanks for the report. I assume the filed issue is: https://github.com/jeevatkm/ReplyWithHeader-Thunderbird/issues/197

Thanks for making us aware of this issue, it sure is interesting. It seems to be a timing issue, and modifications to (unrelated?) core code changed the point in time when add-ons receive the content of the newly opened composer for the first time. The composer initially loads the raw content of the message and later replaces imap:// sources of inline images to data:// URLs. Without this, Thunderbird would also not display these inline images.

For unknown reasons, add-ons have received the "fixed" body in the past, but now get the original body, when they listen for newly opened compose windows. A quick dirty fix would be to wait a few ms before grabbing the content. A delay of 250ms before calling

let composeDetails = await messenger.compose.getComposeDetails(tab.id);

(/modules/compose.js:27)

fixed it for me. This is of course not more than a quick hack. We will investigate how to resolve this.

Hello!
Please guide me step-by-step through how to configure this for myself.

(In reply to John Bieling from comment #1)

Thanks for the report. I assume the filed issue is: https://github.com/jeevatkm/ReplyWithHeader-Thunderbird/issues/197

Thanks for making us aware of this issue, it sure is interesting. It seems to be a timing issue, and modifications to (unrelated?) core code changed the point in time when add-ons receive the content of the newly opened composer for the first time. The composer initially loads the raw content of the message and later replaces imap:// sources of inline images to data:// URLs. Without this, Thunderbird would also not display these inline images.

For unknown reasons, add-ons have received the "fixed" body in the past, but now get the original body, when they listen for newly opened compose windows. A quick dirty fix would be to wait a few ms before grabbing the content. A delay of 250ms before calling

let composeDetails = await messenger.compose.getComposeDetails(tab.id);

(/modules/compose.js:27)

fixed it for me. This is of course not more than a quick hack. We will investigate how to resolve this.

Hi, I actually have the same issue with addon - advanced composer and all pictures disappeared either for reply or forward.

But I also want to point out that previously when I received emails, some inline pictures were received as attachments only and they were missing in the email body.
Now with the new thunderbird, the problem seems to be solved for those problematic emails and the inline pictures display normally.
Hopefully you will not just change thunderbird back to previous setting.

Hopefully you will not just change thunderbird back to previous setting.

We are not reverting the code to an earlier state, but we do like to hear back from you, if it still works for you after the patch has landed.

Attachment #9523751 - Attachment description: Bug 1997519 - Convert mailnews urls of inline images pre-emptive instead of waiting for the error event. r=#thunderbird-reviewers → Bug 1997519 - Convert mailnews urls of inline images pre-emptive instead of waiting for the error event. r=mkmelin

Pushed by alessandro@thunderbird.net:
https://hg.mozilla.org/comm-central/rev/3ce60411546c
Convert mailnews urls of inline images pre-emptive instead of waiting for the error event. r=mkmelin

Status: ASSIGNED → RESOLVED
Closed: 7 months ago
Resolution: --- → FIXED
Backout by alessandro@thunderbird.net: https://hg.mozilla.org/comm-central/rev/eb9067f969ec Backed out changeset 3ce60411546c for causing test failure
Status: RESOLVED → REOPENED
Resolution: FIXED → ---

A different approach is needed for Bug 1997519: instead of modifying the
timing of the composer startup itself, we only need to adjust the compose
API so that any not-yet-converted Gecko resources are converted before
returning the compose body to the extension.

To make loadBlockedImage usable outside of MsgComposeCommands.js, it
is moved into a newly created ComposeUtils.sys.mjs module.

Attachment #9523751 - Attachment is obsolete: true
Attachment #9531431 - Attachment is obsolete: true

A different approach is needed for Bug 1997519: instead of modifying the
timing of the composer startup itself, we only need to adjust the compose
API so that any not-yet-converted Gecko resources are converted before
returning the compose body to the extension.

To make loadBlockedImage usable outside of MsgComposeCommands.js, it
is moved into a newly created ComposeUtils.sys.mjs module.

The reported issue is not limited to WebExtension APIs:

composeWindow.SetComposeDetails({ body: "Something" })

uses editor.document.documentElement.innerHtml = 1 to update the
content of the editor. The error event hanlder used for handling
of blocked images is currently attached to editor.document.body 2.
After the editor content has been replaced as described, this event
listener no longer exists, and blocked images are therefore not handled
anymore.

Comment on attachment 9531439 [details]
Bug 1997519 - Move loadBlockedImage() into ComposeUtils.sys.mjs. r=#thunderbird-reviewers

Revision D275426 was moved to bug 2004890. Setting attachment 9531439 [details] to obsolete.

Attachment #9531439 - Attachment is obsolete: true

Pushed by john@thunderbird.net:
https://hg.mozilla.org/comm-central/rev/9381a94e57af
Make sure the "error" event listerner is not cleared when compose content is updated. r=mkmelin

Status: REOPENED → RESOLVED
Closed: 7 months ago7 months ago
Resolution: --- → FIXED
Target Milestone: --- → 148 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: