Closed Bug 1597891 Opened 11 months ago Closed 9 months ago

Fix or remove MimeObject ResetChannelCharset().

Categories

(MailNews Core :: General, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED
Thunderbird 74.0

People

(Reporter: benc, Assigned: benc)

References

Details

Attachments

(1 file, 3 obsolete files)

+++ This bug was initially created as a clone of Bug #1584473 +++

ResetChannelCharset(), in comm/mailnews/mime/src/mimemoz2.cpp has a code path which ends up in an infinite loop. Since it doesn't seem to have ever been an issue, it's probably safe to assume that the code is never invoked.

  • ResetChannelCharset() is only called from one place - in MimeObject_init_output().
  • Running the comm/mailnews/mime unit tests don't invoke ResetChannelCharset() at all (when running under gdb).

Would be nice to figure out exactly what it's trying to do, and if it's even needed any more.

This should at least stop it crashing if it gets there... (and adds a MOZ_DIAGNOSTIC_ASSERT referencing this bug if it does).

Assignee: nobody → benc
Attachment #9110160 - Flags: review?(jorgk)
Comment on attachment 9110160 [details] [diff] [review]
1597891-resetchannelcharset-fix-1.patch

Review of attachment 9110160 [details] [diff] [review]:
-----------------------------------------------------------------

::: mailnews/mime/src/mimemoz2.cpp
@@ +1774,5 @@
>        obj->options->default_charset && obj->headers) {
> +    // The previous version of this code would have entered an infinite
> +    // loop. But it never showed up, so it's not clear that it is ever
> +    // called...
> +    // See Bug #1584473.

Which bug number do you want here? I suggest we use bug 1597891.

@@ +1777,5 @@
> +    // called...
> +    // See Bug #1584473.
> +    MOZ_DIAGNOSTIC_ASSERT(false, "Should never get here (see Bug 1584473)");
> +
> +    mime_stream_data *msd = GetMSD(obj->options);

No need to use that function, IMHO, obj->options was checked in the if clause above. We might as well revert this change to avoid unnecessary churn.

@@ +1782,3 @@
>      char *ct = MimeHeaders_get(obj->headers, HEADER_CONTENT_TYPE, false, false);
>      if ((ct) && (msd) && (msd->channel)) {
> +      char *cSet = MimeHeaders_get_parameter(ct, "charset", nullptr, nullptr);

OK, so we use a function to extract the charset instead of hand-crafting it. Seems like a good move.

@@ +1787,5 @@
>          msd->channel->SetContentType(nsDependentCString(ct));
>  
>          // Second, if this is a Save As operation, then we need to convert
> +        // to override the output charset.
> +        if (msd->format_out == nsMimeOutput::nsMimeMessageSaveAs) {

Can't we move that condition up? Why get the charset if we're not nsMimeOutput::nsMimeMessageSaveAs?
Attachment #9110160 - Flags: review?(jorgk-bmo)

Sorry, I missed the msd->channel->SetContentType(nsDependentCString(ct)); which is done unconditionally.

Sorry about my wrong comment. I fixed the nits. If you agree, we can land it like this. So now we have better dead code ;-)

Interdiff: https://bugzilla.mozilla.org/attachment.cgi?oldid=9110160&action=interdiff&newid=9112741&headers=1

Attachment #9112741 - Flags: review+
Attachment #9112741 - Flags: feedback?(benc)
Attachment #9112741 - Attachment is patch: true

Thanks Jorg, that all looks great.
I like dead code. It never crashes. We should definitely add more! :-)

Anyway, I shall park this one and revisit it next time I end up doing a deep dive into the mime code (and channel implementations).

Attachment #9110160 - Attachment is obsolete: true
Attachment #9112741 - Flags: feedback?(benc) → feedback+

Pushed by mkmelin@iki.fi:
https://hg.mozilla.org/comm-central/rev/fc1c18cda24b
Remove superfluous infinite loop in MimeObject ResetChannelCharset(). r=jorgk

Status: NEW → RESOLVED
Closed: 11 months ago
Resolution: --- → FIXED
Target Milestone: --- → Thunderbird 72.0

Should have made a try build. This creates oranges across the board, so the code does run: https://treeherder.mozilla.org/#/jobs?repo=comm-central&selectedJob=279022667&revision=fc1c18cda24b0a157d4b6d71c401bf4b5146b17e

Status: RESOLVED → REOPENED
Resolution: FIXED → ---

https://hg.mozilla.org/comm-central/rev/9c5ad9180e9133d9268073251fe2a574cefd7716
Please paste the backout changeset in the future.

Sorry about the bustage, at least we get some idea how to trigger what we thought was dead code, and it must partly be, otherwise it would hang in an endless loop. I guess the diagnostic assert was in the wrong spot, should have been further down in an if-block.

It might be prudent to re-run the Dailies since the diagnostic assert, as you can see, also crashes opt builds.

Flags: needinfo?(benc)
Target Milestone: Thunderbird 72.0 → ---

Indeed, looks like reply to a bugzilla mail causes a crash.
Jörg, would you mind sending me the instructions?

You have to be authorised with the right TC permissions. I'll do it.

Doh! Sorry about that. My fault for a) not running a try build and b) being insufficiently careful about where the ASSERT went.
But like Jörg says, at least we know that the function is being called, and we've got a repeatable test case. So we have a clue as to what issues the function is supposed to be fixing.
I'll work out a local STR and sort out a fix for the fix.

Flags: needinfo?(benc)

No further action here?

So, we've now got a way to exercise this code. Yay mochitests!

The mochitests which hit the ASSERT in the previous patch (ie, by calling ResetChannelCharset()) are:

comm/mail/test/browser/cloudfile/browser_attachmentUrls.js
comm/mail/test/browser/composition/browser_charsetEdit.js
comm/mail/test/browser/content-policy/browser_dnsPrefetch.js
comm/mail/test/browser/folder-display/browser_messageCommandsOnMsgstore.js
comm/mail/test/browser/message-header/browser_replyIdentity.js

I've just been looking at browser_charsetEdit.js.
The test can be run headless (phew), and it lets you attach a debugger, for example:

$ ./mach mochitest --debugger gdb --headless comm/mail/test/browser/composition/browser_charsetEdit.js

Single-stepping though, it all looks like it's doing what it should, as far as I can tell.
(the only bit I've not single-stepped through is the nsMimeMessageSaveAs override-the-output charset bit, but that looks pretty sane).

So, in this patch I've just removed the comment and diagnostic ASSERT. If the try build comes back clean, I think we can call it done.

Attachment #9112741 - Attachment is obsolete: true
Attachment #9121786 - Flags: review?(mkmelin+mozilla)

I don't get it. Did we not agree that the old code would enter an endless loop? And the conclusion was that we'd never get there? So now that we found a test that exercises the code, can we please check why it didn't hang, or maybe the if (ptr) { was never true?

Sorry, yes - the infinite loop in the old code only occurs when the stream output format is nsMimeOutput::nsMimeMessageSaveAs, and this isn't exercised by the current tests.
The old version was a little misleading, as about half the function (including the infinite loop) was in this execution path. In the new version it's about 3 or 4 lines.
The old code inside this path had some brittle bespoke parsing to detect and extract the charset from a content-type header. It was the extraction that had the infinite loop. In the new version, I used an existing mime function to parse the content-type, so we've already got the charset by the time it enters the nsMimeMessageSaveAs branch.
So we've still got 4 lines of uncovered code, which isn't ideal, but that code now looks sane at least.

Comment on attachment 9121786 [details] [diff] [review]
1597891-resetchannelcharset-fix-2.patch

> So we've still got 4 lines of uncovered code, which isn't ideal, but that code now looks sane at least.

IMHO, that where the diagnostic ASSERT must do. The whole aim here is to eventually remove dead code.
Attachment #9121786 - Flags: review-

So what's left is to check if the msd->format_out == nsMimeOutput::nsMimeMessageSaveAs code is needed (by exercising a manual save as test) and depending on whether it works without it or not, keep or remove?

(In reply to Magnus Melin [:mkmelin] from comment #19)

So what's left is to check if the msd->format_out == nsMimeOutput::nsMimeMessageSaveAs code is needed (by exercising a manual save as test) and depending on whether it works without it or not, keep or remove?

I've just been trying to trigger it with a manual "save as", but no joy - it doesn't invoke ResertChannelCharset().

There are test emails in comm/mailnews/test/data/ with a "charset=..." content-type. iso-2022-jp-not-qp.eml is a nice simple one.
I was runnging in gdb, breakpoint on ResetChannelCharset(), drag the .eml file from an outside file browser into a folder, then click "save as..." on the resulting email. Saved it flawlessly, without triggering the breakpoint. Also tried displaying the message with a different char encoding and then clicking "save as", but got the same behaviour (as I'd expect - displaying a message shouldn't influence "save as").

I can't rule out that there's some esoteric path that the nsMimeMessageSaveAs path in ResetChannelCharset() is invoked, but I wouldn't know where to start looking.

This one leaves in the possibly-unused code, but adds back the diagnostic assert Jorg suggested so anyone who does happen to hit it can find their way back here and let us know!

Attachment #9121786 - Attachment is obsolete: true
Attachment #9121786 - Flags: review?(mkmelin+mozilla)
Attachment #9121922 - Flags: review?(mkmelin+mozilla)
Attachment #9121922 - Flags: review?(mkmelin+mozilla) → review+
Comment on attachment 9121922 [details] [diff] [review]
1597891-resetchannelcharset-fix-3.patch

Review of attachment 9121922 [details] [diff] [review]:
-----------------------------------------------------------------

Yes, that what I meant.

::: mailnews/mime/src/mimemoz2.cpp
@@ -1775,1 @@
>      mime_stream_data *msd = (mime_stream_data *)(obj->options->stream_closure);

So funny they got this twice, here ...

@@ -1781,5 @@
>          msd->channel->SetContentType(nsDependentCString(ct));
>  
>          // Second, if this is a Save As operation, then we need to convert
> -        // to override the output charset!
> -        mime_stream_data *msd = GetMSD(obj->options);

... and here.
Attachment #9121922 - Flags: review+
Target Milestone: --- → Thunderbird 74.0

Pushed by mkmelin@iki.fi:
https://hg.mozilla.org/comm-central/rev/c5d3c34a34c9
Remove superfluous infinite loop in MimeObject ResetChannelCharset(). r=mkmelin,jorgk DONTBUILD

Status: REOPENED → RESOLVED
Closed: 11 months ago9 months ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.