Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An invalid character was found in the mail header: ';'. #158

Open
trailmax opened this issue Aug 23, 2016 · 9 comments
Open

An invalid character was found in the mail header: ';'. #158

trailmax opened this issue Aug 23, 2016 · 9 comments

Comments

@trailmax
Copy link

trailmax commented Aug 23, 2016

I've discovered an interesting bug. Today in production logs I've found the following exception:

System.FormatException: An invalid character was found in the mail header: ';'.
at System.Net.Mail.MailAddressParser.ParseLocalPart(String data, Int32& index, Boolean expectAngleBracket, Boolean expectMultipleAddresses)
at System.Net.Mail.MailAddressParser.ParseAddress(String data, Boolean expectMultipleAddresses, Int32& index)
at System.Net.Mail.MailAddressParser.ParseMultipleAddresses(String data)
at System.Net.Mail.MailAddressCollection.ParseValue(String addresses)

I've tracked the issue to an email with an apostrophe. Something like `Mr.O'[email protected]' when using a strongly typed email:

public class TestEmail : Postal.Email
{
    public string To { get; set; }
    public int Name { get; set; }
}


@model TestEmail
To: @Model.Name <@Model.To>
Subject: Fail Test

Hello world


var email = new TestEmail(){
    To = "Mr.O'[email protected]",
    Name = "Mr O'Neil",
}
email.Send(); // this will explode with the exception

The problem tracks down to RazorEngine doing encoding of all the input. So Mr.O'[email protected] is getting translated into Mr.O&#39;[email protected]. You see where the problem comes from? When trying to add this value to MailMessage.To - the above exception is thrown.

Now I've attempted to replace @Model.To with @Html.Raw(Model.To), but Razor Engine fails with message "HtmlHelper is not available".

Solution I've found is to use RawString in cshtml template:

To: @(new RawString(Model.To))

But this adds mental overhead and can easily be forgotten when adding new templates. Any ideas how to improve?

@dudeinthemoon42
Copy link

Hey! Thanks for posting this bug. I actually ran into the same problem today, with the exact same input scenario. I had a series of email strings from a database query coming through and being sent, and the app hit this exception complaining about the input string. The input that triggered the exception was something like O'[email protected], and I was immediately suspicious of the apostrophe. I searched and found your post, and now it makes sense. RazorEngine is definitely trying to encode the apostrophe / HTML-escape it.

I ended up trying both @Html.aw(Model.To.Email) and your work around, @(new RawString(Model.To)). The first one did not compile (complained about an assembly reference), and the second didn't work initially either. I ended up finding where RawString is implemented (it implements IEncodedString in RazorEngine.Text), and then added @using RazorEngine.Text in order to get the context for RawString. IntelliSense was then able to highlight it and recognize it. I reran the input query and the emails went through.

I've gone ahead and started replacing all of my views with this RawString workaround. I can't say that I have any ideas on how to improve on this solution, but I just wanted to thank you for posting and give a heads-up that users might also need to include the using statement I wrote above to get it to work.

@trailmax
Copy link
Author

I suspect there is no easy work-around for this issue. I sense the fundamental problem here - email headers should not be a part of Razor template at all, but this is a paradigm shift for this project and unlikely it'll be changed.

@andrewdavey
Copy link
Owner

When using RazorEngine the Html helper is not available. You can use @Raw(Model.SomeProp) instead.

@trailmax
Copy link
Author

We are using RazorGenerator.MsBuild - it compiles all the *.cshtml files and @Raw() trips the compile process, so that is a no-go unfortunately. RawString works just the same. The problem is having to remember to do it in every email template for every header that might have special characters. But I don't think there will be a work-around to that, other than some integration test that will go through every email template and verify that RawString is applied.

@petrosmm
Copy link

Just an FYI for anyone else still looking. @(new RawString(Model.To)) did not work. I ended up using @Html.Raw(Model.To).

@cavprime
Copy link

cavprime commented Oct 6, 2017

For any fellow sufferers for whom the Raw and RawString didn't work: replace your semicolons with commas.

@pcbbc
Copy link

pcbbc commented Feb 22, 2018

Just encountered this issue effecting the subject line. Isn't it easier to decode the HLML entites back into plain text in Postal's EmailParser? Can anyone see any issue with the following:

        void AssignEmailHeaderToMailMessage(string key, string value, MailMessage message)
        {
            value = HttpUtility.HtmlDecode(value);

Expect a similar fix is required for the text body, if a plain-text view is specified. Haven't found where to fix that yet...

Edit - I think this should do it:

        AlternateView CreateAlternativeView(Email email, string alternativeViewName)
        {
            ...
            if (contentType.StartsWith("text/plain", StringComparison.OrdinalIgnoreCase))
            {
                body = WebUtility.HtmlDecode(body);
            }

            var stream = CreateStreamOfBody(body);

And for messages with only a text body and no AlternateViews:

        void InitializeMailMessage(MailMessage message, string emailViewOutput, Email email)
        {
            ...
                    else
                    {
                        message.IsBodyHtml = messageBody.StartsWith("<");
                        if (!message.IsBodyHtml)
                        {
                            messageBody = HttpUtility.HtmlDecode(messageBody);
                        }
                        message.Body = messageBody;
                    }

@Jhonust
Copy link

Jhonust commented Feb 17, 2024

Thanks for sharing! Identifying and addressing bugs is crucial for maintaining system reliability. Have you tried reviewing recent changes that might have caused this issue? Working apartments collaboratively to debug can lead to a swift resolution.

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

No branches or pull requests

8 participants
@andrewdavey @dudeinthemoon42 @trailmax @petrosmm @pcbbc @cavprime @Jhonust and others