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

Maximal number of errors recorded in Part limited #240

Merged
merged 2 commits into from
Apr 12, 2022

Conversation

pavelbazika
Copy link
Contributor

Hi,

I use enmime to parse emails in my service. It happened that instead of valid mime structure, client sent several MBs of base64 data as input. In such case, enmime consumes a lot of memory (several GBs). It's because readHeader function adds many many warnings in order to "Attempt to detect and repair a non-indented continuation of previous line" as comment says.

In the end, readHeader calls ReadMIMEHeader, which doesn't find valid MIME structure and fails with error and all these warnings are freed. However the memory peak remains and can lead to swapping.

To make it more robust, I'm adding a MaxPartErrors global public variable, which does not allow to record more than limit errors in one part. Default value is 1000 in my PR, but it can be also 0 if you desire, which means no limit and thus there will be no change in current behavior.

Best regards
Pavel

@iredmail
Copy link
Contributor

iredmail commented Apr 8, 2022

Maybe default 1000 is too many. :)

@pavelbazika
Copy link
Contributor Author

Ok, it was meant primarily to avoid extreme memory consumption, what about 100?

@jhillyerd
Copy link
Owner

I think 100 is probably reasonable, in that it's not likely to provide any useful feedback beyond that. For example, my Inbucket project displays these errors to the user to help them improve the quality of the email they send.

In my mind, this should probably be blocked by #90, so they it can be controlled without a global. Let me think on accepting the PR without that though, since I expect 99% of users will never change it.

@iredmail
Copy link
Contributor

iredmail commented Apr 9, 2022

for backward compatible, default value should be unlimited which is same as current release.

@jhillyerd
Copy link
Owner

That's good point, let's give it a high or infinite default for now. I think we are about due to release 0.9.4. I need to look at #90 more and determine if that should be before or after a 1.0.

@pavelbazika
Copy link
Contributor Author

I'll give it default value 0, which means infinite. One more question, should I rather hide the global limit variable behind a getter/setter pair? Could be handy in the future, as you plan some options struct.

@jhillyerd
Copy link
Owner

jhillyerd commented Apr 11, 2022

No need for get/set pair: my plan for options is that they'd would be passed in with each call to decode; they wouldn't be global.

Edit: filed #241 for the broken pull request checks

error.go Outdated
@@ -25,6 +25,9 @@ const (
ErrorMissingRecipient = "no recipients (to, cc, bcc) set"
)

// MaxPartErrors limits number of part parsing errors, 0 means no limit.
Copy link
Owner

Choose a reason for hiding this comment

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

Please set default to 0, and extend comment to note that errors after the limit are ignored, it does not cause parsing to fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, done

@jhillyerd jhillyerd merged commit de45901 into jhillyerd:master Apr 12, 2022
@jhillyerd
Copy link
Owner

Thank you!

@pavelbazika pavelbazika deleted the limit-errors branch June 2, 2022 08:05
@jhillyerd
Copy link
Owner

Heads up that this max errors setting will be available as a Parser option (see #274) after the next release. I will remove the global variable for the release after that.

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.

3 participants